Jump to content

Mavericks kernel testing on AMD (formerly Mountain Lion kernel testing on AMD)


theconnactic
 Share

6,414 posts in this topic

Recommended Posts

Happy new year everybody. (From Belgium)

;)

Edit: By the way I'll make a decrypt app too for permanently decrypting files :)

  • Like 2
Link to comment
Share on other sites

Here is a little something for fun.

It's a gift from a friend of mine...

Quite fitting for a Lion fan ;)

post-100023-0-03237800-1357045857_thumb.png

Link to comment
Share on other sites

Here is a little something for fun.

It's a gift from a friend of mine...

Quite fitting for a Lion fan ;)

happy new year!

 

So worse, I wanted to quit smoking for the new year, but on that new year night/day I used to smoke so much so that my dream in the new year to stop in vain. I'll try next year. nice

 

:wallbash:

 

Andy, but a nice lighter with a lion on it, I'd like to see the mountain lion on my AMD like. :king:

 

What I have noticed a very positive that at the moment a lot of visitors visit our website.Very poisitv! Long live AMD! :welcomeani::thumbsup_anim:

Edited by spakk
Link to comment
Share on other sites

Happy New Year to all xD

 

Installing on my Athlon II X2 215 just now.

 

Booted using mach_sse42_only -v npci=0x3000 GraphicsEnabler=Yes PCIRootUID=1

 

Will post results when done :) Thanks alot Sinetek

Link to comment
Share on other sites

Voila... don't have a Mac/hackintosh around as I'm with my mother but I used her computer to at least write the new permanent decryptor...

Here is the code:

/*
* apb_decrypt.c: Written for Mac OS X 10.6/10.7/10.8. Compile as follows:
*
* gcc -Wall -o apb_decrypt apb_decrypt.c -lcrypto
*
* AnV - Modifications for 64bit and Blowfish decryption method thanks to Sinetek.
* TODO: Implement decrypt using CommonCrypto for Mountain Lion (faster, will do so later)
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <copyfile.h>
#include <mach/mach.h>
#include <mach/machine.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <openssl/blowfish.h>
#define APB_UNPROTECTED_HEADER_SIZE (3 * PAGE_SIZE)
#define APB_FAT_MAX_ARCH					 (5)
#ifndef SG_PROTECTED_VERSION_1
#define SG_PROTECTED_VERSION_1 0x8
#endif /* SG_PROTECTED_VERSION_1 */
static char header_page[PAGE_SIZE];
static char data_page[PAGE_SIZE];
static char xcrypted_page[PAGE_SIZE];
static boolean_t	 apb_initialize(int, BF_KEY*);
static int			 apb_decrypt_page(const void*, void*);
typedef struct {
 uint32_t key;
 uint8_t __d0[22];
 uint32_t datasize;
 uint8_t __d1[10];
 uint8_t cmd;
 uint32_t __d2;
 uint8_t data[32];
} AppleSMCBuffer_t;

static boolean_t
apb_initialize(__unused int mode, BF_KEY* key)
{
 boolean_t result = FALSE;
static const unsigned char plain_key [65] = "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc";
BF_set_key(key, 64, plain_key);
 result = TRUE;
 return result;
}
static int
apb_decrypt_page(const void* in, void* out)
{
 static BF_KEY key;
 static boolean_t initialized = FALSE;
 if (initialized == FALSE) {
		 initialized = apb_initialize(BF_DECRYPT, &key);
		 if (initialized == FALSE) {
				 return -1;
		 }
 }

 const unsigned char* _in = (const unsigned char*)in;
 unsigned char* _out = (unsigned char*)out;
unsigned char null_ivec[32] = {0,};
BF_cbc_encrypt(_in, _out, PAGE_SIZE, &key, null_ivec, BF_DECRYPT);
 return 0;
}
int
main(int argc, char** argv)
{
 int fd_in = -1;
 int fd_out = -1;
unsigned char b64bit = 0;
 if (argc != 3) {
		 fprintf(stderr, "usage: %s <infile> <outfile>\n", argv[0]);
		 exit(1);
 }
 fd_in = open(argv[1], O_RDONLY);
 if (fd_in < 0) {
		 perror("open");
		 exit(1);
 }
 off_t base = (off_t)0;
 off_t ebase_begin = (off_t)0;
 off_t ebase_end = (off_t)0;
 uint32_t n = 0;
 int ret = 0;
 ssize_t nbytes = pread(fd_in, header_page, PAGE_SIZE, (off_t)0);
 if (nbytes != PAGE_SIZE) {
		 ret = -1;
		 goto out;
 }
 uint32_t magic = *(uint32_t*)header_page;
 struct mach_header* mh = (struct mach_header*)0;
#ifdef __LITTLE_ENDIAN__
 if (magic == FAT_CIGAM) {
		 struct fat_header* fh = (struct fat_header*)header_page;
		 uint32_t nfat_arch = ntohl(fh->nfat_arch);
		 if (nfat_arch > APB_FAT_MAX_ARCH) {
				 fprintf(stderr, "too many architectures in Universal binary\n");
				 ret = -1;
				 goto out;
		 }
		 struct fat_arch* fa = (struct fat_arch*)((char*)header_page +
																							 sizeof(struct fat_header));
		 for (n = 0; n < nfat_arch; n++, fa++) {
if (ntohl(fa->cputype) == CPU_TYPE_X86_64) {
base = (off_t)ntohl(fa->offset);
nbytes = pread(fd_in, header_page, PAGE_SIZE, base);
						 if (nbytes != PAGE_SIZE) {
								 fprintf(stderr, "failed to read Universal binary\n");
								 ret = -1;
								 goto out;
						 }
mh = (struct mach_header*)header_page;
b64bit = 1;
break;
				 } else if (ntohl(fa->cputype) == CPU_TYPE_X86) {
						 base = (off_t)ntohl(fa->offset);
						 nbytes = pread(fd_in, header_page, PAGE_SIZE, base);
						 if (nbytes != PAGE_SIZE) {
								 fprintf(stderr, "failed to read Universal binary\n");
								 ret = -1;
								 goto out;
						 }
						 mh = (struct mach_header*)header_page;
b64bit = 0;
						 break;
				 }
		 }
 } else if (magic == MH_MAGIC) {
		 mh = (struct mach_header*)header_page;
b64bit = 0;
		 if (mh->cputype != CPU_TYPE_X86) {
				 fprintf(stderr, "this program supports only x86/x86_64 architecture\n");
				 ret = -1;
				 goto out;
		 }
} else if (magic == MH_MAGIC_64) {
mh = (struct mach_header*)header_page;
b64bit = 1;
		 if (mh->cputype != CPU_TYPE_X86_64) {
				 fprintf(stderr, "this program supports only x86/x86_64 architecture\n");
				 ret = -1;
				 goto out;
		 }
 } else {
		 fprintf(stderr, "not an appropriate Mach-O file\n");
		 ret = -1;
		 goto out;
 }
#else
#error This file can only be compiled on Intel.
#endif
 struct segment_command* text = (struct segment_command*)0;
struct segment_command_64* text64 = (struct segment_command_64 *)0;
 uint32_t ncmds = mh->ncmds;
 struct load_command* lc = (struct load_command*)((char*)mh + sizeof(struct mach_header));
 for (n = 0; n < ncmds; n++) {
		 if (lc->cmd == LC_SEGMENT) {
				 struct segment_command* sc = (struct segment_command*)lc;
				 if (strcmp(sc->segname, SEG_TEXT) == 0) {
						 text = sc;
						 break;
				 }
		 }
if (lc->cmd == LC_SEGMENT_64) {
struct segment_command_64* sc64 = (struct segment_command_64*)lc;
if (strcmp(sc64->segname, SEG_TEXT) == 0) {
text64 = sc64;
break;
}
}
		 lc = (struct load_command*)((char*)lc + lc->cmdsize);
 }
 if (!text && !text64) {
		 fprintf(stderr, "failed to find text segment\n");
		 ret = -1;
		 goto out;
 }
off_t archbase_begin = (off_t)0;
off_t archbase_end = (off_t)0;
if (b64bit == 0) {
	 if (text->flags ^ SG_PROTECTED_VERSION_1) {
			 fprintf(stderr, "not encrypted\n");
			 ret = -1;
			 goto out;
	 }
archbase_begin = (off_t)(text->fileoff + APB_UNPROTECTED_HEADER_SIZE);
archbase_end = archbase_begin + (off_t)(text->filesize - APB_UNPROTECTED_HEADER_SIZE);
} else {
if (text64->flags ^ SG_PROTECTED_VERSION_1) {
fprintf(stderr, "not encrypted\n");
ret = -1;
goto out;
}
	 archbase_begin = (off_t)(text64->fileoff + APB_UNPROTECTED_HEADER_SIZE);
	 archbase_end = archbase_begin + (off_t)(text64->filesize - APB_UNPROTECTED_HEADER_SIZE);
}

 ebase_begin = base + archbase_begin;
 ebase_end = base + archbase_end;
 fd_out = open(argv[2], O_RDWR | O_CREAT | O_EXCL, 0755);
 if (fd_out < 0) {
		 perror("open");
		 ret = -1;
		 goto out;
 }
 ret = fcopyfile(fd_in, fd_out, (copyfile_state_t)0, COPYFILE_ALL);
 if (ret) {
		 perror("copyfile");
		 ret = -1;
		 goto out;
 }
if (b64bit == 0) {
text->flags ^= SG_PROTECTED_VERSION_1;
} else {
text64->flags ^= SG_PROTECTED_VERSION_1;
}
 nbytes = pwrite(fd_out, header_page, PAGE_SIZE, base);
 if (nbytes != PAGE_SIZE) {
		 perror("pwrite");
		 ret = -1;
		 goto out;
 }
 off_t count = ebase_end - ebase_begin;
 if (count % PAGE_SIZE) {
		 fprintf(stderr, "text segment not a multiple of page size\n");
		 ret = -1;
		 goto out;
 }
 while (count > 0) {
		 nbytes = pread(fd_in, data_page, PAGE_SIZE, ebase_begin);
		 if (nbytes != PAGE_SIZE) {
				 perror("pread");
				 ret = -1;
				 goto out;
		 }
		 ret = apb_decrypt_page(data_page, xcrypted_page);
		 if (ret) {
				 fprintf(stderr, "failed to decrypt page\n");
				 goto out;
		 }
		 nbytes = pwrite(fd_out, xcrypted_page, PAGE_SIZE, ebase_begin);
		 if (nbytes != PAGE_SIZE) {
				 perror("pwrite");
				 ret = -1;
				 goto out;
		 }
		 ebase_begin += (off_t)PAGE_SIZE;
		 count -= (off_t)PAGE_SIZE;
 }
 ret = 0;
out:
 if (fd_in >= 0) {
		 close(fd_in);
 }
 if (fd_out >= 0) {
		 close(fd_out);
		 if (ret) {
				 unlink(argv[2]);
		 }
 }
 return(ret);
}

And of course attached here in .c form ;)

apb_decrypt_ml.zip

  • Like 1
Link to comment
Share on other sites

Voila... don't have a Mac/hackintosh around as I'm with my mother but I used her computer to at least write the new permanent decryptor...

Here is the code:

/*
* apb_decrypt.c: Written for Mac OS X 10.6/10.7/10.8. Compile as follows:
*
* gcc -Wall -o apb_decrypt apb_decrypt.c -lcrypto
*
* AnV - Modifications for 64bit and Blowfish decryption method thanks to Sinetek.
* TODO: Implement decrypt using CommonCrypto for Mountain Lion (faster, will do so later)
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <copyfile.h>
#include <mach/mach.h>
#include <mach/machine.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <openssl/blowfish.h>
#define APB_UNPROTECTED_HEADER_SIZE (3 * PAGE_SIZE)
#define APB_FAT_MAX_ARCH					 (5)
#ifndef SG_PROTECTED_VERSION_1
#define SG_PROTECTED_VERSION_1 0x8
#endif /* SG_PROTECTED_VERSION_1 */
static char header_page[PAGE_SIZE];
static char data_page[PAGE_SIZE];
static char xcrypted_page[PAGE_SIZE];
static boolean_t	 apb_initialize(int, BF_KEY*);
static int			 apb_decrypt_page(const void*, void*);
typedef struct {
 uint32_t key;
 uint8_t __d0[22];
 uint32_t datasize;
 uint8_t __d1[10];
 uint8_t cmd;
 uint32_t __d2;
 uint8_t data[32];
} AppleSMCBuffer_t;

static boolean_t
apb_initialize(__unused int mode, BF_KEY* key)
{
 boolean_t result = FALSE;
static const unsigned char plain_key [65] = "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc";
BF_set_key(key, 64, plain_key);
 result = TRUE;
 return result;
}
static int
apb_decrypt_page(const void* in, void* out)
{
 static BF_KEY key;
 static boolean_t initialized = FALSE;
 if (initialized == FALSE) {
		 initialized = apb_initialize(BF_DECRYPT, &key);
		 if (initialized == FALSE) {
				 return -1;
		 }
 }

 const unsigned char* _in = (const unsigned char*)in;
 unsigned char* _out = (unsigned char*)out;
unsigned char null_ivec[32] = {0,};
BF_cbc_encrypt(_in, _out, PAGE_SIZE, &key, null_ivec, BF_DECRYPT);
 return 0;
}
int
main(int argc, char** argv)
{
 int fd_in = -1;
 int fd_out = -1;
unsigned char b64bit = 0;
 if (argc != 3) {
		 fprintf(stderr, "usage: %s <infile> <outfile>\n", argv[0]);
		 exit(1);
 }
 fd_in = open(argv[1], O_RDONLY);
 if (fd_in < 0) {
		 perror("open");
		 exit(1);
 }
 off_t base = (off_t)0;
 off_t ebase_begin = (off_t)0;
 off_t ebase_end = (off_t)0;
 uint32_t n = 0;
 int ret = 0;
 ssize_t nbytes = pread(fd_in, header_page, PAGE_SIZE, (off_t)0);
 if (nbytes != PAGE_SIZE) {
		 ret = -1;
		 goto out;
 }
 uint32_t magic = *(uint32_t*)header_page;
 struct mach_header* mh = (struct mach_header*)0;
#ifdef __LITTLE_ENDIAN__
 if (magic == FAT_CIGAM) {
		 struct fat_header* fh = (struct fat_header*)header_page;
		 uint32_t nfat_arch = ntohl(fh->nfat_arch);
		 if (nfat_arch > APB_FAT_MAX_ARCH) {
				 fprintf(stderr, "too many architectures in Universal binary\n");
				 ret = -1;
				 goto out;
		 }
		 struct fat_arch* fa = (struct fat_arch*)((char*)header_page +
																							 sizeof(struct fat_header));
		 for (n = 0; n < nfat_arch; n++, fa++) {
if (ntohl(fa->cputype) == CPU_TYPE_X86_64) {
base = (off_t)ntohl(fa->offset);
nbytes = pread(fd_in, header_page, PAGE_SIZE, base);
						 if (nbytes != PAGE_SIZE) {
								 fprintf(stderr, "failed to read Universal binary\n");
								 ret = -1;
								 goto out;
						 }
mh = (struct mach_header*)header_page;
b64bit = 1;
break;
				 } else if (ntohl(fa->cputype) == CPU_TYPE_X86) {
						 base = (off_t)ntohl(fa->offset);
						 nbytes = pread(fd_in, header_page, PAGE_SIZE, base);
						 if (nbytes != PAGE_SIZE) {
								 fprintf(stderr, "failed to read Universal binary\n");
								 ret = -1;
								 goto out;
						 }
						 mh = (struct mach_header*)header_page;
b64bit = 0;
						 break;
				 }
		 }
 } else if (magic == MH_MAGIC) {
		 mh = (struct mach_header*)header_page;
b64bit = 0;
		 if (mh->cputype != CPU_TYPE_X86) {
				 fprintf(stderr, "this program supports only x86/x86_64 architecture\n");
				 ret = -1;
				 goto out;
		 }
} else if (magic == MH_MAGIC_64) {
mh = (struct mach_header*)header_page;
b64bit = 1;
		 if (mh->cputype != CPU_TYPE_X86_64) {
				 fprintf(stderr, "this program supports only x86/x86_64 architecture\n");
				 ret = -1;
				 goto out;
		 }
 } else {
		 fprintf(stderr, "not an appropriate Mach-O file\n");
		 ret = -1;
		 goto out;
 }
#else
#error This file can only be compiled on Intel.
#endif
 struct segment_command* text = (struct segment_command*)0;
struct segment_command_64* text64 = (struct segment_command_64 *)0;
 uint32_t ncmds = mh->ncmds;
 struct load_command* lc = (struct load_command*)((char*)mh + sizeof(struct mach_header));
 for (n = 0; n < ncmds; n++) {
		 if (lc->cmd == LC_SEGMENT) {
				 struct segment_command* sc = (struct segment_command*)lc;
				 if (strcmp(sc->segname, SEG_TEXT) == 0) {
						 text = sc;
						 break;
				 }
		 }
if (lc->cmd == LC_SEGMENT_64) {
struct segment_command_64* sc64 = (struct segment_command_64*)lc;
if (strcmp(sc64->segname, SEG_TEXT) == 0) {
text64 = sc64;
break;
}
}
		 lc = (struct load_command*)((char*)lc + lc->cmdsize);
 }
 if (!text && !text64) {
		 fprintf(stderr, "failed to find text segment\n");
		 ret = -1;
		 goto out;
 }
off_t archbase_begin = (off_t)0;
off_t archbase_end = (off_t)0;
if (b64bit == 0) {
	 if (text->flags ^ SG_PROTECTED_VERSION_1) {
			 fprintf(stderr, "not encrypted\n");
			 ret = -1;
			 goto out;
	 }
archbase_begin = (off_t)(text->fileoff + APB_UNPROTECTED_HEADER_SIZE);
archbase_end = archbase_begin + (off_t)(text->filesize - APB_UNPROTECTED_HEADER_SIZE);
} else {
if (text64->flags ^ SG_PROTECTED_VERSION_1) {
fprintf(stderr, "not encrypted\n");
ret = -1;
goto out;
}
	 archbase_begin = (off_t)(text64->fileoff + APB_UNPROTECTED_HEADER_SIZE);
	 archbase_end = archbase_begin + (off_t)(text64->filesize - APB_UNPROTECTED_HEADER_SIZE);
}

 ebase_begin = base + archbase_begin;
 ebase_end = base + archbase_end;
 fd_out = open(argv[2], O_RDWR | O_CREAT | O_EXCL, 0755);
 if (fd_out < 0) {
		 perror("open");
		 ret = -1;
		 goto out;
 }
 ret = fcopyfile(fd_in, fd_out, (copyfile_state_t)0, COPYFILE_ALL);
 if (ret) {
		 perror("copyfile");
		 ret = -1;
		 goto out;
 }
if (b64bit == 0) {
text->flags ^= SG_PROTECTED_VERSION_1;
} else {
text64->flags ^= SG_PROTECTED_VERSION_1;
}
 nbytes = pwrite(fd_out, header_page, PAGE_SIZE, base);
 if (nbytes != PAGE_SIZE) {
		 perror("pwrite");
		 ret = -1;
		 goto out;
 }
 off_t count = ebase_end - ebase_begin;
 if (count % PAGE_SIZE) {
		 fprintf(stderr, "text segment not a multiple of page size\n");
		 ret = -1;
		 goto out;
 }
 while (count > 0) {
		 nbytes = pread(fd_in, data_page, PAGE_SIZE, ebase_begin);
		 if (nbytes != PAGE_SIZE) {
				 perror("pread");
				 ret = -1;
				 goto out;
		 }
		 ret = apb_decrypt_page(data_page, xcrypted_page);
		 if (ret) {
				 fprintf(stderr, "failed to decrypt page\n");
				 goto out;
		 }
		 nbytes = pwrite(fd_out, xcrypted_page, PAGE_SIZE, ebase_begin);
		 if (nbytes != PAGE_SIZE) {
				 perror("pwrite");
				 ret = -1;
				 goto out;
		 }
		 ebase_begin += (off_t)PAGE_SIZE;
		 count -= (off_t)PAGE_SIZE;
 }
 ret = 0;
out:
 if (fd_in >= 0) {
		 close(fd_in);
 }
 if (fd_out >= 0) {
		 close(fd_out);
		 if (ret) {
				 unlink(argv[2]);
		 }
 }
 return(ret);
}

And of course attached here in .c form ;)

 

Hi Andy, this decrypter fixes the problem: waiting for DSMOS ...?

Link to comment
Share on other sites

Bugs in the opemu. Here is the newest build. Athlons will like this, ;)

About the source, yes, I will release them.

Boot flags, busratio.

 

:graduated:

 

http://speedy.sh/hyzD6/mach-kernel

Diff

http://pastebin.com/pn3GmeCN

 

With this build i got stuck at Still Waiting for Root Device after cloning a successful 10.8.0 vanilla installation i have to a HD partition, regardless the flags i use.

 

I'll update to 10.8.2 and try the newest ones!

Link to comment
Share on other sites

Hi Andy, this decrypter fixes the problem: waiting for DSMOS ...?

This will after compilation enable you to make decrypted version of e.g. Finder, Dock, etc...

All Apple encrypted binaries can be decrypted...

Same principle as the Sinetek decryptor...

I used apb_decrypt as the base and modded it for 64 bit binaries too + Sinetek Blowfish decryption method

EDIT: As Sinetek noticed: since SL it uses Blowfish so in theory it should work for SL + Lion + ML

Link to comment
Share on other sites

What is the System.kext from Sinetek for? Do we need it?

 

 

they should resolve the problem hang of waiting for DSMOS, unfortunately Phenom II X6 1100T with no success, it still remains in waiting for dsmos

Link to comment
Share on other sites

they should resolve the problem hang of waiting for DSMOS, unfortunately Phenom II X6 1100T with no success, it still remains in waiting for dsmos

If you have SL or better with Xcode you can compile the .c file.

Next you can check which of the CoreServices are encrypted (Finder, Dock, SystemUIServer, etc...)

Make apb_decrypt and copy to /usr/bin

then you do:

sudo apb_decrypt /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder_unencrypted

Make a backup copy of each Core Service you decrypt just in case...

Link to comment
Share on other sites

If you have SL or better with Xcode you can compile the .c file.

Next you can check which of the CoreServices are encrypted (Finder, Dock, SystemUIServer, etc...)

Make apb_decrypt and copy to /usr/bin

then you do:

sudo apb_decrypt /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder_unencrypted

Make a backup copy of each Core Service you decrypt just in case...

 

 

then I need to install snow leopard, at the moment I have only to test mountain lion for AMD. Mountain Lion running on time only on my Intel laptop. Alternatively, if someone has a Phenom II X6 with a functioning Snow Leopard, which should please proceed according to the instructions of andy! Please

Link to comment
Share on other sites

Im currently stuck on this kernel panic. Cloned existing 10.8.2 installation to usb. Replaced kernel with mach_sse3_only and added system.kext to the extensions folder.

 

AMD Athlon II X2 5000+

 

Try using

mach_sse42_only with the corecrypto kext and without the System kext. Worked for my Athlon

Link to comment
Share on other sites

@mac_carol This is exactly the kind of testing I was looking for, many thanks!!

These findings seem to indicate that the SSSE3 is still not working properly :-(

 

So, for now it seems the best bet is "mach_sse42_only" (less ssse3 running, but still some apps..)

Link to comment
Share on other sites

@mac_carol This is exactly the kind of testing I was looking for, many thanks!!

These findings seem to indicate that the SSSE3 is still not working properly :-(

 

So, for now it seems the best bet is "mach_sse42_only" (less ssse3 running, but still some apps..)

A little question:

I assume the SSE42 only version only sets the sse42 bit in the kernel?

Didn't you say the opemu only works in user space?

This could explain why it crashes on AppleFSCompressionZlib...

  • Like 1
Link to comment
Share on other sites

I think we should put our screenshots in spoiler tags.. The thread is getting hard to scroll through on mobile devices.

 

Just use:

 

[spoiler*]image/screenshot here[/spoiler*] without the star. Results in

 

 

image/screenshot here

 

Link to comment
Share on other sites

I'm on mobile...

Could be worse...

Link to comment
Share on other sites

The standard WebKit based android 4.0 browser on an Acer Liquid Glow E330

Link to comment
Share on other sites

 Share

×
×
  • Create New...