• Welcome to Valhalla Legends Archive.
 
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - brew

#1
It's quite desirable to have a RichEdit control with a background image - however not so easy to accomplish this.
A -very- long time ago, I learned how to do this with Visual Basic 6. It was as simple as setting the WS_EX_TRANSPARENT bit of the extended window style of the richedit contol in question, and slapping an image control with the picture you'd like in back of it. It's unfortunate this isn't so easy for any other language. VB6 does a lot of custom window drawing voodoo with all of its controls, which helps much in this matter.
Working with nothing more than the Win32 API is considerably more difficult, however, because of a god awful blur created when the richedit repaints when scrolling (WM_ERASEBKGND isn't sent to the richedit then).
According to MSDN, with WS_EX_TRANSPARENT enabled, it "should not be painted until siblings beneath the window (that were created by the same thread) have been painted. "

Ok, the first logical thing to try is to send a WM_ERASEBKGND where it didn't...
Subclass the richedit, and on WM_VSCROLL call RedrawWindow with RDW_ERASE | RDW_INTERNALPAINT.
Doesn't work. Has no effect.
It seems like the blur is being painted onto the parent window's background (which is the richedit's background too, since it's transparent), so the next logical thing to do is try to redraw the parent window yourself.
In the richedit's proc, handle WM_PAINT before returning CallWindowProc, where you will FillRect the target area of the RichEdit right before painting. No effect, still blurs.
Then, you notice, every time the richedit is painted to, the parent window receives a neat WM_ERASEBKGND message too! Maybe it'd work if you tried to manually erase the background here? No.
So on, and so forth....
Then, I had asked myself if making it a transparent window was even necessary.
Long story short, it is. For some reason it seems the background clearing/painting is done in the richedit's internal painting routine (what were they thinking?). Any paints made in a WM_PAINT handler before calling the original window proc would result in a neat painting over your picasso.

So there must be some way to do this, right?
There are, theoretically. I don't know how to do either of these, which might be potential solutions:
1). Make a brush with CreatePatternBrush using the image you'd like to paint the background of the richedit with, then you'd somehow be able to have it paint the background on its own with the brush you indicate.
2). Have it output what it would paint into a memory DC, so you're able to TransparentBlt it onto the final window, effectively getting rid of the background it painted on by itself.

I couldn't solve this problem two years ago when I threw this feature into my bot, so I kind of cheated by using microsoft's implementation of #2: WS_EX_COMPOSITED.
This is basically a bit that enables double buffering for a window and all of its child windows, only problem is that it can't be used on a control (only top-level windows or MDI children), so you'll see its undesirable effects on all child windows of that parent window, which include an ungodly amount of CPU usage, and the inability to have column headers in a listview. It took me a while to figure out the exact cause of the latter, as it had caused a constant stream of NM_CUSTOMDRAW WM_NOTIFY messages to be sent to the parent from an unidentified hWnd which turned out to be the column component.
Back then, I looked at it as a temporary fix, but over time I'd forgotten about it. Now that I go back to implement a neat feature I just thought up which utilizes richedit background drawing, I'd remembered, and attempted to make a more permanent solution with my 2 years more experience. I failed again.

P.S.
You might take 5 minutes of your time and search for "transparent richedit" on google, and you'll find a wealth of CodeProject and related sites with articles on exactly this, but before you post links to those here, do download the demo applications and try them out yourself. None of them are able to overcome the unfortunate blur effect.

EDIT*
if anyone needs to see for themselves, this is the blur effect happening to the codeproject article's demo application.  apparently, this doesn't happen to cuphead. i suspect if this is true and i wasn't being bullshitted to, there is a newer version of riched32.dll out there with this problem fixed.
#2
Battle.net Bot Development / .......0x43?
June 06, 2009, 05:55 PM
Just started getting this today, right after the 0x54 packet in the SRP logon

ff 43 08 00 00 00 00 00

...can anyone packetlog warcraft 3 and see if there's a response to this packet? I don't have it.
#3
I've gotten far enough to compile crap with MSVC9, but can't debug.
When I try to, I get a cute dialog that states "'<debugfilenameexecutablehere>' does not contain", a checkbox with "Do not prompt in the future", an OK and a Cancel button.

I assume it ment to say it doesn't contain debug information, and indeed the executable doesn't!

My compiler options (yes, i know a few are obsolete and ignored, i didn't get around to finding the VC9 equivalents yet):
"/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fp"Debug/blah.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /GF /c "

Linker options:
"libcmtd.lib msimg32.lib version.lib zdll.lib dbghelp.lib crypt32.lib WS2_32.lib comctl32.lib msvcrtd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/blah.pdb" /debug /machine:I386 /nodefaultlib /out:"Debug/blah.exe" /pdbtype:sept"

I assume part of the reason is because the .pdb file the compiler cranks out is ment for version 7 or greater, as the first few bytes of the file state "Microsoft C/C++ MSF 7.00". Also, it produces a vc90.pdb file, not vc60.pdb.
Updating the component(s) used for debugging would surely fix this all, right?
I don't know where they are in MSVC6's directory.

Suppose I find a good workaround for this. Then, how would I...
• Run mspdbsrv -start -spawn before c1.exe is executed
• Starting a new project, have the IDE fill in the correct default compiler options
?
#4
Uh oh...
Quote
[03:04:31 PM] Warden module f7c4cac8d33c92fa04bac7667fe3bc1d.mod requested.
[03:04:32 PM] Module getting address to 0x7c800000!AddVectoredExceptionHandler() ...
[03:04:32 PM] Module getting address to 0x7c800000!RemoveVectoredExceptionHandler() ...
[03:04:32 PM] Module allocated 2024 bytes.
[03:04:32 PM] Module allocated 60 bytes.
[03:04:32 PM] Module allocated 44 bytes.
[03:04:32 PM] Module getting address to 0x7c800000!CreateToolhelp32Snapshot() ...
[03:04:32 PM] Module getting address to 0x7c800000!Module32First() ...
[03:04:32 PM] Module getting address to 0x7c800000!Module32Next() ...
[03:04:32 PM] Module getting address to 0x7c800000!wine_get_unix_file_name() ...
=[?
#5
General Discussion / What's up with google?
January 31, 2009, 09:01 AM
Any search result provided by google is accompanied with a cute "This site may harm your computer." As a result it won't let you click directly onto any links. I find this very annoying.
Did they get owned? Is it just a bug? What's the ETA on a fix?

edit:
It's fixed now
http://www.f-secure.com/weblog/archives/00001595.html
#6
Battle.net Bot Development / homebrew snp?
December 24, 2008, 12:24 AM
I'm sure people have attempted this before...

So I wrote my caps.dat, packed it to an mpq, made my dll, concatinated the mpq to the dll with copy /b irc.dll + sdfg.mpq irc.snp, thus making my snp.

However, since I use WinMPQ to mpqify it, it's obviously not going to have a (signature) file for SFileAuthenticateArchive to check, so it inevitably fails, and sets the second arg to 1 (error code, im guessing  ?)

So i've got something like this:

.text:150302CB                 push    edx             ; int *something
.text:150302CC                 push    edi             ; hArchive
.text:150302CD                 call    SFileAuthenticateArchive
.text:150302D2                 mov     eax, [ebp+var_C]
.text:150302D5                 cmp     eax, ebx
.text:150302D7                 jz      short loc_150302E2
.text:150302D9                 cmp     eax, 5          ; jump is taken here
.text:150302DC                 jb      loc_15030369

for now, i patch eax from 1 to 5 at 302D9
I'm under the impression that the rest of the code would run just fine with/without the success of SFileAuthenticateArchive, since it's just a validity check after all, but after it's loaded, DllMain is called, SnpQuery is called twice, then DllMain again.
Here's my code (so far) for my snp:


unsigned long bnet_dword = 'LOLZ';
const char *bnet_string = "SC IRC Rofl";
const char *bnet_infostring = "blahblahblah blah blah blah blahddy blah blah blah, bladdy blah blah. blarg blarg ah.";
                            //"An active connection to an Internet provider, or a direct connection to the Internet.";
int bnet_numlist[] = {
0x24, /*sizeof this structure*/
0x20000000,
0x200,
0x10,
0x100,
0x5DC, /*1500*/
0x1F4, /*500*/
4,
2
};

/*
.data:19041D74 dword_19041D74  dd 24h                  ; DATA XREF: SnpQuery
.data:19041D78                 dd 20000000h
.data:19041D7C                 dd 200h
.data:19041D80                 dd 10h
.data:19041D84                 dd 100h
.data:19041D88                 dd 5DCh
.data:19041D8C                 dd 1F4h
.data:19041D90                 dd 4
.data:19041D94                 dd 2
*/

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:

break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
__asm nop
}
MessageBox(0, "ROFLMAO", 0, 0);
return true;
}

extern "C" {  ////////////////////////////

__declspec(dllexport) bool SnpBind(int arg1, int *arg2) {
MessageBox(0,"SnpBind!",0,0);
if (!arg1) {
if (arg2) {
*arg2 = (int)functiontable;
return true;
}
}
return false;
}

__declspec(dllexport) bool SnpQuery(int arg1, int *arg2, int *arg3, int *arg4, int *arg5) {
MessageBox(0,"SnpQuery!",0,0);
if (arg1 || !arg2 || !arg3 || !arg4 || !arg5)
return false;
*arg2 = (int)bnet_dword;
*arg3 = (int)&bnet_string;
*arg4 = (int)&bnet_infostring;
*arg5 = (int)bnet_numlist;
return true;
}

}     //////////////////////////////


Apparently there's an access violation somewhere along the road a bit later (ebx is 1 at 4DE037) , after the dll's been detached. I must be doing something wrong.. anybody have a clue whatsup?
#8
Battle.net Bot Development / SEXP_IX86_1152_1153.mpq
September 11, 2008, 02:12 PM
New patch for Starcraft/Brood War:
SEXP_IX86_1152_1153.mpq

Quote
Starcraft and Brood War Patch Information

--------------------------------------------------------------------------------
- patch 1.15.3
--------------------------------------------------------------------------------

  Bug Fixes
- Fixed a communication bug affecting third party leagues.
- Alt-F6 no longer stalls the game on Windows.
- Game now works correctly on versions of Mac OS X which do not support 256-color
  mode.

I'm assuming the verbyte didn't change at all.

EDIT** Oh wow, cool new BNUpdate icon
#9
I've noticed that the Diablo II 0x51 packet passes, even with a blank exe info string, and a totally invalid exe version value (0xCCCCCCCC). I know that you aren't required to pass a valid exe info field, but what about the exe version? Historically, this value was enforced. What's going on? Can anyone else verify?
#10
General Programming / comctl32.dll versions...
July 15, 2008, 12:07 AM
Apparently, to be able to use an hbitmap as the source for the background image pf a listview with the LVM_SETBKIMAGE message, you must have version 6.0 or higher of comctl32.dll, however I only have 5.82, which according to this, 5.82 is the most current version. Note 4 of that page says the following:
Quote
ComCtl32.dll version 6 is not redistributable. If you want your application to use ComCtl32.dll version 6, you must add an application manifest that indicates that version 6 should be used if it is available.
Well, seeing as how the highest version is 5.82, how is version 6 going to be available? Does microsoft think that people don't need this type of functionality?

Also, I've noticed visual basic can do a ton of things with no problems that I would have, for example when the WS_EX_TRANSPARENT style is set on a RichEdit control in vb6, it works just fine. However, when I do the same myself, the text blurs when moved, and must be invalidated then redrawn. I would have no problem with redrawing it, but the problem is that I don't know when. Then there's the problem with the listview items' back color. In vb6, this is no problem. The text is drawn right to the listview without the box around the text. However, I can't do the same- It asks for a colorref, and a colorref I must give. After toying around with it a bit, I find that making the color -1 does the trick, however, like any null brush, it would draw whatever was previously drawn over it until the picture is redrawn.
All in all, my project is a royal gdi wreck. Help would be appreciated!
#11
Is there any reason for BnetAuth's implementation of CheckRevision would succeed, but produce an invalid checksum for WAR3 CR requests? It does pad the files, i checked.
It produces 0xdd585324 for the checksum when I pass "ver-IX86-5.mpq" for the mpq name, and
"B=2951995818 A=2013111097 C=2841202106 4 A=A^S B=B^C C=C+A A=A-B" for the checksum formula. BNCSUtil's checksum for the same parameters is very different (and correct according to the server), yet this exact same cr algorithm works just perfect with diablo 2. Any ideas? And yes, i am using up-to-date hash files.
#12
The following code works just fine when extracting anything from starcraft maps, but SFileOpenArchive seems to fail when trying to extract anything else (for example, ExtraWork dlls, unless they don't have (listfile)s) and files within internal directories. Can anyone see what seems to be the problem?

void ExtractMPQ(char *filename, char *toget) {
HMODULE hLibStorm = LoadLibrary("Storm.dll");
FILE *file;
char *asdf;
unsigned long hMPQ, hMPQFile, filesize, highdword;
unsigned long SFileDestroy      = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(262));
unsigned long SFileSetLocale    = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(272));
unsigned long SFileOpenArchive  = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(266));
unsigned long SFileOpenFileEx   = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(268));
unsigned long SFileGetFileSize  = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(265));
unsigned long SFileReadFile     = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(269));
unsigned long SFileCloseFile    = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(253));
unsigned long SFileCloseArchive = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(252));
__asm {
push 'enUS'
call SFileSetLocale
test eax, eax
jz errored

call SFileDestroy
test eax, eax
jz errored

lea eax, [hMPQ]
push eax
push 0
push 0
mov eax, filename
push eax
call SFileOpenArchive
test eax, eax
jz errored

lea eax, [hMPQFile]
push eax
push 0
push toget
push hMPQ
call SFileOpenFileEx
test eax, eax
jz errored

lea eax, [highdword]
push eax
push hMPQFile
call SFileGetFileSize
mov filesize, eax
cmp eax, -1
je errored

push eax
call malloc
pop ecx
mov asdf, eax

push 0
push 0
push filesize
push eax
push hMPQFile
call SFileReadFile
test eax, eax
jz errored

push '\\'
push toget
call strchr
add esp, 8
mov ecx, toget
test eax, eax
jz over
mov ecx, eax
inc ecx

over:

mov highdword, 'bw'
lea eax, [highdword]
push eax
push ecx
call fopen
mov file, eax
add esp, 8

push eax
push filesize
push 1
push asdf
call fwrite
add esp, 10h

push file
call fclose
pop ecx

push asdf
call free
pop ecx

push hMPQFile
call SFileCloseFile
test eax, eax
jz errored

push hMPQ
call SFileCloseArchive
test eax, eax
jz errored

push hLibStorm
call dword ptr [FreeLibrary]
}
return;
errored:
AddChat(vbRed, "ExtractMPQ Failed!");
return;
}

...

ExtractMPQ("C:\\Documents and Settings\\Owner\\Desktop\\IX86Mindsight.mpq", "(listfile)");
#13
Computer Support Issues / Linux bncsutil?
February 18, 2008, 02:39 PM
Does anyone out there have a linux bncsutil version?
I kinda need it ^^;;, cause i'll be damned if i have to port all the hashing-stuff on vim...
i would use an actual IDE but i can't, because apparently xorg can't find an input driver matching 'mouse' and 'kbd'... and when I do start it, it's nothing more then a black screen with an X outlined in white in the center. :/
#14
General Programming / bncache.dat splitter
February 16, 2008, 09:41 PM
So i decided to make a quick splitter for bncache.dat, but it seems to mix up a few things here and there (for example, half of the ToS is in icons.bni). Can anyone see what i might be doing wrong?

EDIT** I looked at it in a hex editor closer and it appears as if i'm doing nothing wrong at all-- but apparently the function that gets the file has something to protect against this. am i overlooking something in the headers?


#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

char *memmem(char* haystack, size_t hl, const char* needle, size_t nl);

int main() {
const char *blah = "\x44\x01\0\0\0\0\0\0\0\0\0\0";
const char *filename = "C:\\Program Files\\Starcraft\\bncache.dat";
char *found;
char strbuf[0x80];
char strbuf2[0x80];
char *buffer = (char *)malloc(1000000);
char *tmpbuffer = buffer;
FILE *file = fopen(filename, "rb");
if (!file) {
printf("Invalid file.\n");
return 0;
}
ZeroMemory(buffer, 1000000);
fread(buffer, 1, 975439, file);
fclose(file);
int i = 0;
while (tmpbuffer <= (char *)(buffer + 1000000)) {
found = memmem(tmpbuffer, buffer + 1000000 - tmpbuffer, blah, 12);
if (found) {
strncpy(strbuf, found + 0x40, 0x80);
tmpbuffer = found + 12;
printf("0x%08x  %s\n", tmpbuffer - buffer - 12, strbuf);
sprintf(strbuf2, "C:\\Documents and Settings\\Owner\\Desktop\\Cache\\%s", strbuf);
file = fopen(strbuf2, "wb");
if (file) {
fwrite(tmpbuffer + 312, 1, memmem(tmpbuffer,
buffer + 1000000 - tmpbuffer, blah, 12) - tmpbuffer - 312, file);
fclose(file);
} else {
printf("fopen() failed\n");
}
i++;
} else {
break;
}
}
free(buffer);
return 0;
}

char *memmem(char *haystack, size_t hl, const char *needle, size_t nl) {
if (nl > hl)
return NULL;
for (int i = hl - nl + 1; i; --i) {
if (!memcmp(haystack, needle, nl))
return haystack;
++haystack;
}
return NULL;
}
#15
Battle.net Bot Development / BNCS 0x3B?
February 16, 2008, 08:39 AM
I've never seen it on bnet, but i do see it being parsed at 1902D160 of battle.snp...
it appears to have a structure of:

(FILETIME) Filetime of patch?
(STRING) Name of patch?

The name is copied to a global char array.
After that, InitalizeDownloader is called, with the filetime and the name being passed to it.
also the fastcall params are:
ecx == 80000001h <--the BNFTP file request id (note on bnetdocs we only have 80000004 and 80000005)
edx == 3 <--- download type? maybe?

Since right after that call, the string "requesting latest version" passed to NotifyMsg, it's safe to name this packet SID_UPDATEREQ. or something.
Does anyone know more about it?

EDIT** i am assuming this was only for legacy (pre-xsha1 style) logons, since the same functionality can be achieved by parsing the extra info string in the 0x51 response, and an 0x33 request.
#16
Battle.net Bot Development / Maiev.mod
February 08, 2008, 10:36 PM
Starts at 190333C9 in battle.snp, after some weak-as-hell static string encryption. Discuss.

My guess: The last name of the blizzard employee who implemented it?
#17
So I was reading over the log file, and I saw this:

Quote
00005333765i[BIOS ] Booting from 0000:7c00
00005340147i[BIOS ] int13_diskette: unsupported AH=41

Wtf? I would've never caught it if I haven't looked over the log.
I just want to find if the bios supports the extended drive interrupts...


mov ah, 41h
mov bx, 55AAh
int 13h
jc usechs


is what I use to call it.

the carry flag is set when LBA is not supported.

How could it not support 41h? It's not like it's very obscure or anything...
http://en.wikipedia.org/wiki/Int_13

What do i do!? I was planning on supporting the ah 42h read function instead if lba is supported. But since this isn't working, i highly doubt that any other extended drive function would work as well.
#18
Assembly Language (any cpu) / int 13h returns 0Eh?
January 07, 2008, 06:31 PM
According to some documentation i have, 0x0E means "control data address mark detected (hard disk)". What does this mean? How do I fix it? Here's my code:

readdisk:
mov ah, 2 ;2 = read, 3 = write
mov al, 1 ;# of sectors
mov ch, 1 ;low 8 bits of cylinder #
mov cl, 1 ;sector # 1-63 (bits 0-5), 6-7 hard disk only
mov dh, 1 ;head number
mov dl, 80h  ;drive # (bit 7 set for hard disk)
mov bx, 8000h ;es:bx data buffer
int 13h
ret
#19
General Discussion / Configuring VMware Player....
January 01, 2008, 12:08 AM
Ahhh! it's a pain in the ass. I want to get it booting from the floppy drive..... but it gives me the error "Could not connect to floppy "A:". Please correct your configuration and then re-attempt to connect the virtual floppy drive. Failed to connect to virtual device floppy0." I'm nowhere near an expert on this, and I just got my instructions from here, using the near exact same configuration (just changed the paths, that's all). Also, are the last two bytes of the MBR supposed to be AA55h? or is it the other way around...
#20

unsigned int GetIcon(unsigned long client, unsigned long flags) {
unsigned int rettemp = 0;
switch (client) {
case CLIENT_CHAT: //0x43484154:
rettemp++;
case CLIENT_W3XP: //0x57335850:
rettemp++;
case CLIENT_WAR3: //0x57415233:
rettemp++;
case CLIENT_W2BN: //0x5732424E:
rettemp++;
case CLIENT_D2XP: //0x44325850:
rettemp++;
case CLIENT_D2DV: //0x44324456:
rettemp++;
case CLIENT_DSHR: //0x44534852:
rettemp++;
case CLIENT_DRTL: //0x4452544C:
rettemp++;
case CLIENT_JSTR: //0x4A535452:
rettemp++;
case CLIENT_SSHR: //0x53534852:
rettemp++;
case CLIENT_SEXP: //0x53455850:
rettemp++;
}
if ((flags & 1) == 1)
rettemp = 12;
if ((flags & 2) == 2)
rettemp = 13;
if ((flags & 4) == 4)
rettemp = 14;
if ((flags & 8) == 8)
rettemp = 15;
if ((flags & 32) == 32)
rettemp = 16;
if ((flags & 64) == 64)
rettemp = 17;
return rettemp;
}


using MSVC6, compiles to:


0040B540   55               PUSH EBP
0040B541   8BEC             MOV EBP,ESP
0040B543   51               PUSH ECX
0040B544   51               PUSH ECX
0040B545   8365 FC 00       AND DWORD PTR SS:[EBP-4],0
0040B549   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
0040B54C   8945 F8          MOV DWORD PTR SS:[EBP-8],EAX
0040B54F   817D F8 5254534A CMP DWORD PTR SS:[EBP-8],4A535452
0040B556   77 3C            JA SHORT 0040B594
0040B558   817D F8 5254534A CMP DWORD PTR SS:[EBP-8],4A535452
0040B55F   0F84 96000000    JE 0040B5FB
0040B565   817D F8 54414843 CMP DWORD PTR SS:[EBP-8],43484154
0040B56C   74 55            JE SHORT 0040B5C3
0040B56E   817D F8 56443244 CMP DWORD PTR SS:[EBP-8],44324456
0040B575   74 6F            JE SHORT 0040B5E6
0040B577   817D F8 50583244 CMP DWORD PTR SS:[EBP-8],44325850
0040B57E   74 5F            JE SHORT 0040B5DF
0040B580   817D F8 4C545244 CMP DWORD PTR SS:[EBP-8],4452544C
0040B587   74 6B            JE SHORT 0040B5F4
0040B589   817D F8 52485344 CMP DWORD PTR SS:[EBP-8],44534852
0040B590   74 5B            JE SHORT 0040B5ED
0040B592   EB 7C            JMP SHORT 0040B610
0040B594   817D F8 50584553 CMP DWORD PTR SS:[EBP-8],53455850
0040B59B   74 6C            JE SHORT 0040B609
0040B59D   817D F8 52485353 CMP DWORD PTR SS:[EBP-8],53534852
0040B5A4   74 5C            JE SHORT 0040B602
0040B5A6   817D F8 4E423257 CMP DWORD PTR SS:[EBP-8],5732424E
0040B5AD   74 29            JE SHORT 0040B5D8
0040B5AF   817D F8 50583357 CMP DWORD PTR SS:[EBP-8],57335850
0040B5B6   74 12            JE SHORT 0040B5CA
0040B5B8   817D F8 33524157 CMP DWORD PTR SS:[EBP-8],57415233
0040B5BF   74 10            JE SHORT 0040B5D1
0040B5C1   EB 4D            JMP SHORT 0040B610
0040B5C3   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5C6   40               INC EAX
0040B5C7   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5CA   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5CD   40               INC EAX
0040B5CE   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5D1   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5D4   40               INC EAX
0040B5D5   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5D8   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5DB   40               INC EAX
0040B5DC   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5DF   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5E2   40               INC EAX
0040B5E3   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5E6   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5E9   40               INC EAX
0040B5EA   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5ED   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5F0   40               INC EAX
0040B5F1   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5F4   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5F7   40               INC EAX
0040B5F8   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B5FB   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B5FE   40               INC EAX
0040B5FF   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B602   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B605   40               INC EAX
0040B606   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B609   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B60C   40               INC EAX
0040B60D   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
0040B610   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]
0040B613   83E0 01          AND EAX,1
0040B616   83F8 01          CMP EAX,1
0040B619   75 07            JNZ SHORT 0040B622
0040B61B   C745 FC 0C000000 MOV DWORD PTR SS:[EBP-4],0C
0040B622   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]
0040B625   83E0 02          AND EAX,2
0040B628   83F8 02          CMP EAX,2
0040B62B   75 07            JNZ SHORT 0040B634
0040B62D   C745 FC 0D000000 MOV DWORD PTR SS:[EBP-4],0D
0040B634   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]
0040B637   83E0 04          AND EAX,4
0040B63A   83F8 04          CMP EAX,4
0040B63D   75 07            JNZ SHORT 0040B646
0040B63F   C745 FC 0E000000 MOV DWORD PTR SS:[EBP-4],0E
0040B646   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]
0040B649   83E0 08          AND EAX,8
0040B64C   83F8 08          CMP EAX,8
0040B64F   75 07            JNZ SHORT 0040B658
0040B651   C745 FC 0F000000 MOV DWORD PTR SS:[EBP-4],0F
0040B658   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]
0040B65B   83E0 20          AND EAX,20
0040B65E   83F8 20          CMP EAX,20
0040B661   75 07            JNZ SHORT 0040B66A
0040B663   C745 FC 10000000 MOV DWORD PTR SS:[EBP-4],10
0040B66A   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]
0040B66D   83E0 40          AND EAX,40
0040B670   83F8 40          CMP EAX,40
0040B673   75 07            JNZ SHORT 0040B67C
0040B675   C745 FC 11000000 MOV DWORD PTR SS:[EBP-4],11
0040B67C   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0040B67F   C9               LEAVE
0040B680   C3               RETN

In release mode too. With all optimizations turned on.
* brew throws up