I just finished setting up my shiny new FreeBSD 7 desktop system. After struggling to get Flash9 working properly, I finally settled on Opera running under Wine. Everything works perfectly except for one tiny problem... I want websites to see me as a FreeBSD user even though I'm running Opera/Wine, dammit.
- Code: Select all
/*
* uass - User Agent String Switcher
*
* Inserts an arbitrary User Agent string into
* Opera's opera.dll
*
* Tested:
* Opera 9.52 for Windows on Windows XP and FreeBSD under Wine
*
* For now, we're going to insist that this UA
* must be <= 73 bytes. This is the longest UA
* found in the binary and starts at offset 0x6B2DD8
* and ends at 0x6B2E20 (after upx decompression).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define D_OFFSET1 0x6B2DD8
#define D_OFFSET2 0x6B2E20
#define D_UA "Opera/9.52 (FreeBSD i386/Wine; U; en)"
#define MAX_UA_LEN 73
void usage(char *name);
void die(char *msg);
void cleanup(void);
int setup(void);
int check_ua(char *ua, char **nua);
int patch(long int offset1, long int offset2, char *ua, int recomp);
int main(int argc, char *argv[]) {
int ch = 0;
char *ua = D_UA;
char *nua = NULL;
long int offset1 = D_OFFSET1;
long int offset2 = D_OFFSET2;
int recomp = 1;
atexit(&cleanup);
while((ch = getopt(argc, argv, "s:e:a:c")) != -1) {
switch(ch) {
case 's': offset1 = strtol(optarg, NULL, 0);
break;
case 'e': offset2 = strtol(optarg, NULL, 0);
break;
case 'a': ua = optarg;
break;
case 'c': recomp = 0;
break;
default: usage(argv[0]);
}
}
argc -= optind;
argv += optind;
if((offset2 - offset1) >= MAX_UA_LEN || ((offset2 - offset1) < 1))
die("Invalid offsets!\n");
if(! check_ua(ua, &nua))
die("Invalid UA string!\n");
if(! setup())
die("Preparing opera.dll failed!\n");
if(! patch(offset1, offset2, ua, recomp))
die("Patching opera.dll failed!\n");
printf("UA slot 2 is now:\n%s\n"
"Visit \"opera:config#UserAgent|SpoofUserAgentID\"\n"
"And set the value to '2' if you haven't yet.\n", nua);
free(nua);
return 0;
}
void usage(char *name) {
printf("USAGE: %s [-c] [-s offset] [-e offset] [-a \"UA\"]\n", name);
exit(0);
}
void die(char *msg) {
printf("%s", msg);
exit(0);
}
int setup(void) {
FILE *bak;
FILE *cur;
char ch;
int ret = 0;
if((bak = fopen("opera.bak.dll", "rb")) == NULL) {
if((cur = fopen("opera.dll", "rb")) == NULL)
die("Can't find opera.dll!\n");
if((bak = fopen("opera.bak.dll", "wb")) == NULL)
die("Can't create a backup opera.dll!\n");
else {
while(! feof(cur)) {
ch = fgetc(cur);
if(ferror(cur))
die("Error reading opera.dll!\n");
if(! feof(cur))
fputc(ch, bak);
if(ferror(bak))
die("Can't write to opera.dll backup!\n");
}
fclose(cur);
fclose(bak);
}
}
printf("Decompressing opera.dll\n");
ret = system("upx -d opera.dll > upxout");
if(ret == -1 || ret == 127 || ret == 1)
die("upx decompression failed!\n");
return 1;
}
int patch(long int offset1, long int offset2, char *ua, int recomp) {
FILE *fp;
int ret = 0;
if((fp = fopen("opera.dll", "r+b")) == NULL)
return -1;
printf("Inserting UA...\n");
if(fseek(fp, offset1, SEEK_SET) != 0)
die("a mysterious death...\n");
if(fwrite(ua, sizeof(char), MAX_UA_LEN, fp) != MAX_UA_LEN)
return -1;
if(ferror(fp))
return -1;
fclose(fp);
if(recomp) {
printf("Recompressing (may take a minute)...\n");
ret = system("upx -3 opera.dll > upxout");
if (ret == -1 || ret == 127 || ret == 1)
die("upx compression seems to have failed!\n");
}
return 1;
}
int check_ua(char *ua, char **nua) {
int ua_len = 0;
char *tmp = NULL;
ua_len = strlen(ua);
if(ua_len > MAX_UA_LEN)
return 0;
if((tmp = malloc(sizeof(char) * MAX_UA_LEN + 1)) == NULL)
die("Memory allocation failed!\n");
*nua = (char *) memset(tmp, 0x00, MAX_UA_LEN + 1);
*nua = (char *) memset(tmp, ' ', MAX_UA_LEN);
strncpy(*nua, ua, ua_len);
return 1;
}
void cleanup(void) {
remove("upxout");
}
TO USE(windows)
- Get a copy of the upx command (http://upx.sourceforge.net/) and place it in Opera's directory
- Compile the obove source (gcc -o uass uass.c) and put the resulting binary in Opera's directory
- Close Opera
- From a command shell in Opera's directory type:
uass -a "Your Agent String Here" - Visit opera:config#UserAgent|SpoofUserAgentID and set that value to '2'.
(You only have to do this last step once)
NOTES
- The steps vary slightly between Windows/Linux/FreeBSD
- Your Agent strings must be 73 characters or less
- It would be way cooler to insert the UA string while Opera is running... but I don't know how to do that
- Have a nice day
-- Tue Mar 17, 2009 9:47 am --
Just an update for myself and anyone else that might be using the latest release(9.64) of Opera to do missions that require a user agent change. Things in the dll have changed and moved around but the above program will still work, it just needs some flags.
- Code: Select all
./uass -s 0x6c80c8 -e 0x6c8110 -a "Opera/9.64 (FreeBSD i386/Wine; U; en)"

