Author Topic: [ASM/PseudoC] lockdown04::GetVersionHash  (Read 4035 times)

0 Members and 1 Guest are viewing this topic.

Offline Joe

  • B&
  • x86
  • Hero Member
  • *****
  • Posts: 10319
  • In Soviet Russia, text read you!
    • View Profile
    • Github
[ASM/PseudoC] lockdown04::GetVersionHash
« on: April 19, 2007, 03:16:31 am »
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.
« Last Edit: April 19, 2007, 04:02:06 am by Joe[x86/64] »
I'd personally do as Joe suggests

You might be right about that, Joe.


Offline Hdx

  • The Hdx!
  • Full Member
  • ***
  • Posts: 311
  • <3 Java/Cpp/VB/QB
    • View Profile
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #1 on: April 19, 2007, 04:29:45 pm »
Maby you should comment the part of the code that actually converts the chat array into the 32-bit interger returned in that function.
Code: [Select]
.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
http://img140.exs.cx/img140/6720/hdxnew6lb.gif
09/08/05 - Clan SBs @ USEast
 [19:59:04.000] <DeadHelp> We don't like customers.
 [19:59:05.922] <DeadHelp> They're assholes
 [19:59:08.094] <DeadHelp> And they're never right.

Offline Newby

  • x86
  • Hero Member
  • *****
  • Posts: 10877
  • Thrash!
    • View Profile
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #2 on: April 19, 2007, 11:56:37 pm »
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?
- Newby
http://www.x86labs.org

Quote
[17:32:45] * xar sets mode: -oooooooooo algorithm ban chris cipher newby stdio TehUser tnarongi|away vursed warz
[17:32:54] * xar sets mode: +o newby
[17:32:58] <xar> new rule
[17:33:02] <xar> me and newby rule all

I'd bet that you're currently bloated like a water ballon on a hot summer's day.

That analogy doesn't even make sense.  Why would a water balloon be especially bloated on a hot summer's day? For your sake, I hope there wasn't too much logic testing on your LSAT. 

Offline Hdx

  • The Hdx!
  • Full Member
  • ***
  • Posts: 311
  • <3 Java/Cpp/VB/QB
    • View Profile
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #3 on: April 20, 2007, 12:30:22 am »
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
http://img140.exs.cx/img140/6720/hdxnew6lb.gif
09/08/05 - Clan SBs @ USEast
 [19:59:04.000] <DeadHelp> We don't like customers.
 [19:59:05.922] <DeadHelp> They're assholes
 [19:59:08.094] <DeadHelp> And they're never right.

Offline warz

  • Hero Member
  • *****
  • Posts: 1134
    • View Profile
    • chyea.org
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #4 on: April 20, 2007, 12:36:01 am »
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.
http://www.chyea.org/ - web based markup debugger

Offline Hdx

  • The Hdx!
  • Full Member
  • ***
  • Posts: 311
  • <3 Java/Cpp/VB/QB
    • View Profile
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #5 on: April 20, 2007, 01:29:18 am »
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
http://img140.exs.cx/img140/6720/hdxnew6lb.gif
09/08/05 - Clan SBs @ USEast
 [19:59:04.000] <DeadHelp> We don't like customers.
 [19:59:05.922] <DeadHelp> They're assholes
 [19:59:08.094] <DeadHelp> And they're never right.

Offline Joe

  • B&
  • x86
  • Hero Member
  • *****
  • Posts: 10319
  • In Soviet Russia, text read you!
    • View Profile
    • Github
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #6 on: April 20, 2007, 02:02:07 am »
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.
I'd personally do as Joe suggests

You might be right about that, Joe.


Offline iago

  • Leader
  • Administrator
  • Hero Member
  • *****
  • Posts: 17914
  • Fnord.
    • View Profile
    • SkullSecurity
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #7 on: April 20, 2007, 08:58:14 am »
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


:-)

Offline Newby

  • x86
  • Hero Member
  • *****
  • Posts: 10877
  • Thrash!
    • View Profile
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #8 on: April 20, 2007, 09:42:36 am »
lol iago.
- Newby
http://www.x86labs.org

Quote
[17:32:45] * xar sets mode: -oooooooooo algorithm ban chris cipher newby stdio TehUser tnarongi|away vursed warz
[17:32:54] * xar sets mode: +o newby
[17:32:58] <xar> new rule
[17:33:02] <xar> me and newby rule all

I'd bet that you're currently bloated like a water ballon on a hot summer's day.

That analogy doesn't even make sense.  Why would a water balloon be especially bloated on a hot summer's day? For your sake, I hope there wasn't too much logic testing on your LSAT. 

Offline Blaze

  • x86
  • Hero Member
  • *****
  • Posts: 7136
  • Canadian
    • View Profile
    • Maide
Re: [ASM/PseudoC] lockdown04::GetVersionHash
« Reply #9 on: April 22, 2007, 01:40:46 am »
Haha, now that's impressive!  :)
And like a fool I believed myself, and thought I was somebody else...