When I was looking at some CheckRevision stuff today, I found this. Here's what I ended up with for a quick commenting of it. IDA did most of it.
Enjoy!
; ver-IX86-5.dll 0x10002A78
; int __cdecl GetExeInfo(LPCSTR lpFileName,int)
GetExeInfo proc near
FileTime= FILETIME ptr -150h
SystemTime= _SYSTEMTIME ptr -10h
lpFileName= dword ptr 8
arg_4= dword ptr 0Ch
push ebp
mov ebp, esp
sub esp, 150h
push esi
mov esi, [ebp+arg_4]
lea eax, [ebp+FileTime]
push edi
and byte ptr [esi], 0
push eax ; lpFindFileData
push [ebp+lpFileName] ; lpFileName
call ds:FindFirstFileA
mov edi, eax
cmp edi, 0FFFFFFFFh
jz short loc_10002AF
; At this point we can either jump to the bottom, or get the exe info
lea eax, [ebp+SystemTime]
push eax ; lpSystemTime
lea eax, [ebp-13Ch]
push eax ; lpFileTime
call ds:FileTimeToSystemTime
movzx eax, [ebp+SystemTime.wSecond]
push dword ptr [ebp-130h]
and byte ptr [ebp-105h], 0
push eax
movzx eax, [ebp+SystemTime.wMinute]
push eax
movzx eax, [ebp+SystemTime.wHour]
push eax
push 64h
movzx eax, [ebp+SystemTime.wYear]
cdq
pop ecx
idiv ecx
movzx eax, [ebp+SystemTime.wDay]
push edx
push eax
movzx eax, [ebp+SystemTime.wMonth]
push eax
lea eax, [ebp-124h]
push eax
push offset aS02u02u02u02u0 ; "%s %02u/%02u/%02u %02u:%02u:%02u %u" ;this is the format given to wsprintf
push esi ; LPSTR
call ds:wsprintfA
add esp, 28h
push edi ; hFindFile
call ds:FindClose
; here's where we return stuffs
loc_10002AFF:
pop edi
pop esi
leave
retn
GetExeInfo endp
Pseudo-C++:
LPCSTR GetExeInfo(LPCSTR lpFileName, int dwUnk0)
{
int edi = FindFirstFileA(lpFileName);
if(edi == 0x0FFFFFFFFh)
{
return 0;
}
else
{
// I'm not sure how we got the File Time. Pretend we did and it's in ft
SystemTime st = FileTimeToSystemTime(ft);
return wsprintf("%s %02u/%02u/%02u %02u:%02u:%02u %u", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, /* unknown, [ebp-150], something outside our space */);
}
}
...?
Quote(2:45:35 AM) Blaze: This is what I bet Skywing was thinking when he patched BNLS: "What? Is this all they did? Hrm... I wonder if I can write the code for this before I finish a yawn... "
(2:45:49 AM) Joe: Probably.
(2:46:10 AM) Blaze: What you're thinking is "WTF IS GOING ON1!111!1 :'("
(2:48:30 AM) Joe: yeah.
yep, that's the easy part -- now do the rest of it :P
By the way, if you want a list of Storm.dll exports, http://www.javaop.com/~ron/documents/Storm.txt
What's at ebp-150, iago?
How the hell would I know?
Incidentally, you're going to get the wrong checksum returned if you try to call that function directly, because it'll checksum the current running program.
Quote from: iago on March 17, 2007, 04:27:48 PM
How the hell would I know?
I thought [ebp-150] was some standard thing in assembly. Kind of like how if someone asked you what [esi] is you could say it's the stack pointer (I think), you know?
Quote from: iago on March 17, 2007, 04:27:48 PM
Incidentally, you're going to get the wrong checksum returned if you try to call that function directly, because it'll checksum the current running program.
I sort of noticed that, but I just discarded it as something that I just didn't understand.
esp is the stack pointer.
ebp is often the frame pointer.
Anything can be stored on the stack, and the frame is part of the stack.
You'll find it all in my pamphlet (http://www.skullsecurity.org/wiki).
Quote from: Joex86] link=topic=8833.msg112321#msg112321 date=1174193402]
Quote from: iago on March 17, 2007, 04:27:48 PM
How the hell would I know?
I thought [ebp-150] was some standard thing in assembly. Kind of like how if someone asked you what [esi] is you could say it's the stack pointer (I think), you know?
It's probably a local variable.
Another sign to myself that I'm developing dyslexia. ebp-150 isn't used anywhere. Eh, oh well.
Anyhow, I did some more work on figuring this out. And woo, I've got a full copy of IDA now. ^_^
.text:10002B89 ; int __cdecl GetExeInfo(LPCSTR lpcstr_exepath,LPCSTR lpcstr_return)
.text:10002B89 GetExeInfo proc near ; CODE XREF: CheckRevision+38p
.text:10002B89
.text:10002B89 FileTime = FILETIME ptr -150h
.text:10002B89 SystemTime = _SYSTEMTIME ptr -10h
.text:10002B89 lpcstr_exepath = dword ptr 8
.text:10002B89 lpcstr_return = dword ptr 0Ch
.text:10002B89
.text:10002B89 push ebp
.text:10002B8A mov ebp, esp
.text:10002B8C sub esp, 150h
.text:10002B92 push esi
.text:10002B93 mov esi, [ebp+lpcstr_return] ; From here on, ESI points to lpcstr_return
.text:10002B96 lea eax, [ebp+FileTime]
.text:10002B9C push edi
.text:10002B9D and byte ptr [esi], 0
.text:10002BA0 push eax ; LPWIN32_FIND_DATA
.text:10002BA1 push [ebp+lpcstr_exepath] ; exe path
.text:10002BA4 call ds:FindFirstFileA ;
.text:10002BA4 ; This chunk of code gets a handle to the EXE,
.text:10002BA4 ; moves it to EDI, and then makes sure that it
.text:10002BA4 ; actually exists
.text:10002BA4 ;
.text:10002BA4 ; Also, the second argument of FindFirstFile will
.text:10002BA4 ; become a reference to a WIN32_FIND_DATA struct,
.text:10002BA4 ; and [ptr+4] is "FILETIME ftCreationTime".
.text:10002BA4 ;
.text:10002BAA mov edi, eax
.text:10002BAC cmp edi, 0FFFFFFFFh
.text:10002BAF jz short loc_10002C10
.text:10002BB1 lea eax, [ebp+SystemTime]
.text:10002BB4 push eax
.text:10002BB5 lea eax, [ebp-13Ch] ; Pointer to the FILETIME struct, obtained from FindFirstFile
.text:10002BBB push eax
.text:10002BBC call ds:FileTimeToSystemTime ; This assigns [ebp+SystemTime] to the proper value.
.text:10002BC2 movzx eax, [ebp+SystemTime.wSecond]
.text:10002BC6 push dword ptr [ebp-130h] ; This apparently is the length of the EXE file
.text:10002BCC and byte ptr [ebp-105h], 0
.text:10002BD3 push eax
.text:10002BD4 movzx eax, [ebp+SystemTime.wMinute]
.text:10002BD8 push eax
.text:10002BD9 movzx eax, [ebp+SystemTime.wHour]
.text:10002BDD push eax
.text:10002BDE push 64h
.text:10002BE0 movzx eax, [ebp+SystemTime.wYear]
.text:10002BE4 cdq
.text:10002BE5 pop ecx
.text:10002BE6 idiv ecx
.text:10002BE8 movzx eax, [ebp+SystemTime.wDay]
.text:10002BEC push edx
.text:10002BED push eax
.text:10002BEE movzx eax, [ebp+SystemTime.wMonth]
.text:10002BF2 push eax
.text:10002BF3 lea eax, [ebp-124h] ; This points to a string specifing the exe name.
.text:10002BF3 ; Example: starcraft.exe
.text:10002BF9 push eax
.text:10002BFA push offset aS02u02u02u02u0 ; "%s %02u/%02u/%02u %02u:%02u:%02u %u"
.text:10002BFF push esi ; This is where the string is returned to
.text:10002BFF ; Note: This points to [ebp+lpcstr_return]
.text:10002C00 call ds:wsprintfA ;
.text:10002C00 ; return wsprintf(esi,
.text:10002C00 ; "%s %02u/%02u/%02u %02u/%02u/%02u %u", [ebp-124h],
.text:10002C00 ; wMonth, wDay, wYear % 100, wHour, wMinute,
.text:10002C00 ; wSecond, dword ptr [ebp-130h])
.text:10002C00 ;
.text:10002C00 ; starcraft.exe MO/DY/YR HR:MN:SC size
.text:10002C00 ;
.text:10002C06 add esp, 28h
.text:10002C09 push edi
.text:10002C0A call ds:FindClose
.text:10002C10
.text:10002C10 loc_10002C10: ; CODE XREF: GetExeInfo+26j
.text:10002C10 pop edi
.text:10002C11 pop esi
.text:10002C12 leave
.text:10002C13 retn
.text:10002C13 GetExeInfo endp
I haven't been terribly active as of late... is the updated battle.net logon closed information?
You probably mean CheckRevision -- the protocol itself hasn't changed.
It's not necessarily closed -- more of a lack of it in the first place. Yoni and/or Skywing know it, obviously, or have at least cracked it to the point where BNLS can run it. They're not releasing it.
Unless someone hasn't come out and said it yet, warz is the closest, and his information is released but incomplete.
You probably know, but this is the old EXE info. This isn't used by StarCraft anymore, but is still active in Diablo II and WarCraft II, I think.
the method in which checkrevision obtains the information regarding the file itself has not changed, and you're somewhat reinventing the wheel here. point is you know what that function does, but so does everyone else, and has for years, so just rename it in IDA, and move along. also, if you're picking at it for learning sake, there's easier functions in checkrevision to learn from - specifically the checkrevision function itself. just look at it as a whole, and try to make a flow chart, or psuedocode draw up of the function itself. it's pretty simple with a few function calls, and a loop or two.