I just finished commenting this out. I don't have a clue how, but according to Hdx, reading my IDB file's comments helped him learn somewhat, so maybe I'll help someone else out a bit? Dunno.
.text:00401250 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:00401250
.text:00401250 ; This function doesn't appear to have any arguments
.text:00401250 ; Attributes: bp-based frame
.text:00401250
.text:00401250 ; int __cdecl GetVersionHash()
.text:00401250 GetVersionHash proc near ; CODE XREF: CheckRevision+98p
.text:00401250
.text:00401250 sBuffer = dword ptr -218h
.text:00401250 dwHandle = dword ptr -214h
.text:00401250 len = dword ptr -210h
.text:00401250 sFilename = byte ptr -20Ch
.text:00401250 checksum = dword ptr -4
.text:00401250
.text:00401250 push ebp
.text:00401251 mov ebp, esp
.text:00401253 sub esp, 218h
.text:00401259 mov eax, dword_404000
.text:0040125E xor eax, ebp
.text:00401260 mov [ebp+checksum], eax
.text:00401263 and [ebp+sBuffer], 0
.text:0040126A and [ebp+len], 0
.text:00401271 push esi
.text:00401272 push edi
.text:00401273 push 260 ; nSize
.text:00401278 lea eax, [ebp+sFilename]
.text:0040127E push eax ; lpFilename
.text:0040127F push 0 ; hModule
.text:00401281 call ds:GetModuleFileNameW ; C++: eax = GetModuleFileNameW(0, sFilename, 260);
.text:00401281 ;
.text:00401281 ; This gets the ModuleFileName of the current process, since hModule is null
.text:00401287 test eax, eax
.text:00401289 jz short loc_4012FB
.text:0040128B lea eax, [ebp+dwHandle]
.text:00401291 push eax ; lpdwHandle
.text:00401292 lea eax, [ebp+sFilename]
.text:00401298 push eax ; lptstrFilename
.text:00401299 call GetFileVersionInfoSizeW ; C++: infoSize = GetFileVersionInfoSizeW(sFilename, dwHandle)
.text:0040129E mov edi, eax
.text:004012A0 push edi ; dwBytes
.text:004012A1 call HeapAllocWrapper ; C++: eax = HeapAllocWrapper(infoSize)
.text:004012A6 mov esi, eax ; esi points to our new heap
.text:004012A8 test esi, esi
.text:004012AA pop ecx
.text:004012AB jz short lblTryAnsi ; Theres no checking on GetFileVersionInfoSizeA, so it could
.text:004012AB ; be either function that failed, but it was probably GetFileVersionInfoA
.text:004012AD push esi ; lpData
.text:004012AE push edi ; dwLen
.text:004012AF push [ebp+dwHandle] ; dwHandle
.text:004012B5 lea eax, [ebp+sFilename]
.text:004012BB push eax ; lptstrFilename
.text:004012BC call GetFileVersionInfoW ; C++: (bool)eax = GetFileVersionInfoW(sFilename, dwHandle, edi, esi)
.text:004012BC ;
.text:004012BC ; EDI points to the info size
.text:004012BC ; ESI points to the heap
.text:004012C1 test eax, eax
.text:004012C3 jz short lblTryAnsi
.text:004012C5 lea eax, [ebp+len]
.text:004012CB push eax ; puLen
.text:004012CC lea eax, [ebp+sBuffer]
.text:004012D2 push eax ; lplpBuffer
.text:004012D3 push offset SubBlockW ; lpSubBlock
.text:004012D8 push esi ; pBlock
.text:004012D9 call VerQueryValueW ; VerQueryValueW(esi, SubBlock, sBuffer, len)
.text:004012D9 ;
.text:004012D9 ; ESI points to the heap
.text:004012D9 ; SubBlockW is a WCHAR, "\"
.text:004012DE test eax, eax
.text:004012E0 jz short lblTryAnsi
.text:004012E2 mov eax, [ebp+sBuffer]
.text:004012E8 test eax, eax
.text:004012EA jz short lblTryAnsi
.text:004012EC cmp [ebp+len], 34h
.text:004012F3 jnb lblFinish
.text:004012F9 jmp short lblTryAnsi
.text:004012FB ; ---------------------------------------------------------------------------
.text:004012FB
.text:004012FB loc_4012FB: ; CODE XREF: GetVersionHash+39j
.text:004012FB mov esi, [ebp+dwHandle]
.text:00401301
.text:00401301 lblTryAnsi: ; CODE XREF: GetVersionHash+5Bj
.text:00401301 ; GetVersionHash+73j ...
.text:00401301 push 520 ; nSize
.text:00401306 lea eax, [ebp+sFilename]
.text:0040130C push eax ; lpFilename
.text:0040130D push 0 ; hModule
.text:0040130F call ds:GetModuleFileNameA ; C++: eax = GetModuleFileNameA(0, sFilename, 520);
.text:00401315 test eax, eax
.text:00401317 jz lblFail
.text:0040131D lea eax, [ebp+dwHandle]
.text:00401323 push eax ; lpdwHandle
.text:00401324 lea eax, [ebp+sFilename]
.text:0040132A push eax ; lptstrFilename
.text:0040132B call GetFileVersionInfoSizeA ; C++: infoSize = GetFileVersionInfoSizeA(sFilename, dwHandle)
.text:00401330 mov edi, eax
.text:00401332 push edi ; dwBytes
.text:00401333 call HeapAllocWrapper ; C++: eax = HeapAllocWrapper(infoSize)
.text:00401338 mov esi, eax
.text:0040133A test esi, esi
.text:0040133C pop ecx
.text:0040133D jz short lblFail ; Theres no checking on GetFileVersionInfoSizeA, so it could
.text:0040133D ; be either function that failed, but it was probably GetFileVersionInfoA
.text:0040133F push esi ; lpData
.text:00401340 push edi ; dwLen
.text:00401341 push [ebp+dwHandle] ; dwHandle
.text:00401347 lea eax, [ebp+sFilename]
.text:0040134D push eax ; lptstrFilename
.text:0040134E call GetFileVersionInfoA ; C++: (bool)eax = GetFileVersionInfoA(sFilename, dwHandle, edi, esi)
.text:0040134E ;
.text:0040134E ; EDI points to the info size
.text:0040134E ; ESI points to the heap
.text:00401353 test eax, eax
.text:00401355 jz short lblFail
.text:00401357 lea eax, [ebp+len]
.text:0040135D push eax ; puLen
.text:0040135E lea eax, [ebp+sBuffer]
.text:00401364 push eax ; lplpBuffer
.text:00401365 push offset SubBlockA ; "\\"
.text:0040136A push esi ; pBlock
.text:0040136B call VerQueryValueA ; VerQueryValueW(esi, SubBlock, sBuffer, len)
.text:0040136B ;
.text:0040136B ; ESI points to the heap
.text:0040136B ; SubBlockA is a CHAR, "\"
.text:00401370 test eax, eax
.text:00401372 jz short lblFail
.text:00401374 mov eax, [ebp+sBuffer]
.text:0040137A test eax, eax
.text:0040137C jz short lblFail
.text:0040137E cmp [ebp+len], 34h ; Check if the length of
.text:0040137E ; lpBuffer is less than 52
.text:00401385 jb short lblFail
.text:00401387
.text:00401387 lblFinish: ; CODE XREF: GetVersionHash+A3j
.text:00401387 movzx edx, byte ptr [eax+16h]
.text:0040138B xor ecx, ecx
.text:0040138D mov ch, [eax+12h]
.text:00401390 push esi ; lpMem, memory to be freed by HeapFree
.text:00401391 mov cl, [eax+10h]
.text:00401394 movzx eax, byte ptr [eax+14h]
.text:00401398 shl ecx, 8
.text:0040139B or ecx, edx
.text:0040139D shl ecx, 8
.text:004013A0 or ecx, eax
.text:004013A2 mov edi, ecx
.text:004013A4 call HeapFreeWrapper
.text:004013A9 mov eax, edi
.text:004013AB jmp short lblExit
.text:004013AD ; ---------------------------------------------------------------------------
.text:004013AD
.text:004013AD lblFail: ; CODE XREF: GetVersionHash+C7j
.text:004013AD ; GetVersionHash+EDj ...
.text:004013AD push esi ; lpMem, memory to be freed by HeapFree
.text:004013AE call HeapFreeWrapper
.text:004013B3 xor eax, eax
.text:004013B5
.text:004013B5 lblExit: ; CODE XREF: GetVersionHash+15Bj
.text:004013B5 pop ecx
.text:004013B6 mov ecx, [ebp+checksum]
.text:004013B9 pop edi
.text:004013BA xor ecx, ebp
.text:004013BC pop esi
.text:004013BD call TextEcxAgainst404000
.text:004013C2 leave
.text:004013C3 retn
.text:004013C3 GetVersionHash endp
EDIT -
I attached both my IDB file and the original DLL. They've both got a ".txt" added to the end, so take that into account if you try to use them.
Maby you should comment the part of the code that actually converts the chat array into the 32-bit interger returned in that function.
.text:00401387 movzx edx, byte ptr [eax+16h]
.text:0040138B xor ecx, ecx
.text:0040138D mov ch, [eax+12h]
.text:00401390 push esi ; lpMem, memory to be freed by HeapFree
.text:00401391 mov cl, [eax+10h]
.text:00401394 movzx eax, byte ptr [eax+14h]
.text:00401398 shl ecx, 8
.text:0040139B or ecx, edx
.text:0040139D shl ecx, 8
.text:004013A0 or ecx, eax
.text:004013A2 mov edi, ecx
.text:004013A4 call HeapFreeWrapper
.text:004013A9 mov eax, edi
Basically what I get from that is that it nabs eax+10h through eax+16h and sifts it around to convert it to the 32-bit integer.
~Hdx
I don't get how you could learn something from just reading the disassembly. Maybe I'm more of a hands-on type of guy...
You also fail to document the random jumps and where those end up.
GetVersionHash returns 0 if it fails? What is it supposed to return? The hash value?
Its the 0x1000901, its the EXE Version. This thing never changes in crevs cuz it's used to figure out what patch to give out.
~Hdx
Where does this function appear in relation to checkrevision? Is this still the same function that simply returns the game version dword? If so, why are you still stuck on this? It hasn't changed in forever - there's no reason to get bogged down by this.
Yes its the old function, and he isnt getting bogged down, he was working on it cuz he didn't know what it was. Once he relized it, he moved on.
I am working on it cuz i'm trying to learn.
Warz, whats your AIM? I need your help.
~Hdx
I recognized it about 3/4 the way through the work I did. Originally, I saw it doing the versioning stuff on the EXE and I automatically assumed it was building the statstring, and I wanted to figure that out. But at the point where I noticed that wasn't what it was doing, I had nearly finished commenting it up pretty nicely anyhow.
Sometimes, experience helps with that kind of thing:
(04:12:25 PM) HdxEvilBlake: .text:00401387 movzx edx, byte ptr [eax+16h]
.text:0040138B xor ecx, ecx
.text:0040138D mov ch, [eax+12h]
.text:00401390 push esi
.text:00401391 mov cl, [eax+10h]
.text:00401394 movzx eax, byte ptr [eax+14h]
.text:00401398 shl ecx, 8
.text:0040139B or ecx, edx
.text:0040139D shl ecx, 8
.text:004013A0 or ecx, eax
.text:004013A2 mov edi, ecx
(04:12:44 PM) iagox86: That looks like the version hash
:-)
lol iago.
Haha, now that's impressive! :)