?
Hallo squay,
ich weiß zwar nicht, was die Funktion eigentlich bezwecken soll, da ich den gesamten Kontext nicht kenne. Aber dennoch habe ich das Disassembly mal kommentiert und eine mögliche C-Implementation geschrieben. Aufgrund des oben genannten Problems habe ich mich beim C Code sehr nah an das Disassembly Listing gehalten. Ich hoffe, dass es dir weiterhilft.
Ich gehe mal davon aus, dass du verhindern willst, dass explode_bomb() aufgerufen wird. Wenn du dir die Funktion ansiehst, dann wirst du bemerken, dass es da letzten Endes doch auf den Wert eines spezifischen Array Elements ankommt (wie es mir scheint).
08048efb <phase_5>:
; Stack frame of phase_5:
; function typedef: DWORD __cdecl phase_5(char* pszStringToScan)
; Segment:
; EBP+0x08: pszStringToScan
; EBP+0x04: Return address
; EBP+0x00: Old EBP value
; EBP-0x04: ESI backup
; EBP-0x08: EBX backup
; ...
; EBP-0x12: First sscanf format list argument
; EBP-0x16: Second sscanf format list argument
8048efb: 55 push ebp ; Backup old EBP value to use as stack pointer
8048efc: 89 e5 mov ebp,esp ; Copy value from ESP to EBP. EBP stack frame pointer setup done
8048efe: 56 push esi ; Backup ESI to use it
8048eff: 53 push ebx ; Backup EBX to use it
8048f00: 83 ec 20 sub esp,0x20 ;Subtract 0x20 bytes from ESP to allocate stack memory
8048f03: 8d 45 f0 lea eax,[ebp-16] ; Load expression ebp-0x16 to EAX. It's the pointer to the second format list arg for sscanf
8048f06: 89 44 24 0c mov DWORD PTR [esp+12],eax ; Copy value from EAX to [ESP+0x12]. At ESP+0x12 is the fourth function arg
8048f0a: 8d 45 f4 lea eax,[ebp-12] ; Load expression EBP-0x12 to EAX. It's the pointer to the first format list arg for sscanf
8048f0d: 89 44 24 08 mov DWORD PTR [esp+8],eax ; Copy value from EAX to [ESP+0x08]. At ESP+0x08 is the third function arg
8048f11: c7 44 24 04 e4 a6 04 mov DWORD PTR [esp+4],0x804a6e4 ; Copy constant VA value to [ESP+0x04]. At ESP+0x04 is the second function arg
8048f19: 8b 45 08 mov eax,DWORD PTR [ebp+8] ; Copy value at [EBP+0x08] (argument of phase_5()) to EAX. The string which shall be scanned is passed to phase_5() function
8048f1c: 89 04 24 mov DWORD PTR [esp],eax ; Copy value from EAX to [ESP]. At ESP is the first function arg
8048f1f: e8 8c f9 ff ff call 80488b0 <__isoc99_sscanf@plt> ; Call sscanf function (cdecl)
8048f24: 83 f8 01 cmp eax,0x1 ; Perform comparition with EAX and 0x01
8048f27: 7f 05 jg 8048f2e <phase_5+0x33> ; If EAX is greater then jump to address
8048f29: e8 d3 06 00 00 call 8049601 <explode_bomb> ; Else call explode_bomb(). So we don't want to get to this place
8048f2e: 8b 45 f4 mov eax,DWORD PTR [ebp-12] ; Copy DWORD at [EBP-12] (first format list arg) to EAX
8048f31: 83 e0 0f and eax,0xf ; Perform AND operation with EAX and 0x0F
8048f34: 89 45 f4 mov DWORD PTR [ebp-12],eax ; Copy new value back to the stack var
8048f37: 83 f8 0f cmp eax,0xf ; Perform comparision with EAX and 0x0F
8048f3a: 74 29 je 8048f65 <phase_5+0x6a> ; If both are equal jump to the address. That shall not happen.
8048f3c: b9 00 00 00 00 mov ecx,0x0 ; Initialize ECX with 0x00000000 by copying
8048f41: ba 00 00 00 00 mov edx,0x0 ; Initialize EDX with 0x00000000 by copying
8048f46: bb c0 a5 04 08 mov ebx,0x804a5c0 ; Copy VA constant to EBX. It is the base address of a DWORD array
;Begin loop
8048f4b: 83 c2 01 add edx,0x1 ; Add 0x01 to EDX
8048f4e: 8b 04 83 mov eax,DWORD PTR [ebx+eax*4] ; Copy the DWORD at EBX+EAX*4 to EAX. Get index offset by EAX*4
8048f51: 01 c1 add ecx,eax ; Add EAX to ECX
8048f53: 83 f8 0f cmp eax,0xf ; Perform comparison with EAX and 0x0F. To end this loop EAX must have the value 0x0F at its lowest byte
8048f56: 75 f3 jne 8048f4b <phase_5+0x50> ; If both are not equal jump to loop begin.
; End loop
8048f58: 89 45 f4 mov DWORD PTR [ebp-12],eax ; Copy EAX back to the stack var
8048f5b: 83 fa 0f cmp edx,0xf ; Compare EDX with 0x0F
8048f5e: 75 05 jne 8048f65 <phase_5+0x6a> ; If not equal jump to the fail part. So, basically, EDX must have the value 0x0F at its lowest byte to avoid explode_bomb() call
8048f60: 39 4d f0 cmp DWORD PTR [ebp-16],ecx ; Compare DWORD at [EBP-0x016] with ECX
8048f63: 74 05 je 8048f6a <phase_5+0x6f> ; If both are equal jump to the success part!
8048f65: e8 97 06 00 00 call 8049601 <explode_bomb> ; Call explode_bomb() function. So we don't want to get to this place from 8048f3a and 8048f5e
8048f6a: 83 c4 20 add esp,0x20 ; Remove the allocated stack memory by adding
8048f6d: 5b pop ebx ; Restore EBX
8048f6e: 5e pop esi ; Restore ESI
8048f6f: 5d pop ebp ; Restore old EBP
8048f70: c3 ret ; Restore return address
// Possible C implementation
DWORD __cdecl phase_5_8048efb(char* pszStringToScan)
{
static unsigned int uia804a5c0[...] = {...};
DWORD dwEBP12;
DWORD dwEBP16;
if (sscanf(pszStringToScan, "%d %d", &dwEBP12, &dwEBP16) <= 0x01)
explode_bomb();
DWORD dwEAX = dwEBP12 & 0x0F;
dwEBP12 = dwEAX;
if (dwEAX == 0x0F)
explode_bomb();
DWORD dwECX, dwEDX;
dwECX = dwEDX = 0;
while (dwEAX != 0x0F) {
dwEAX = *(DWORD*)((DWORD)uia804a5c0 + dwEAX * 4); //uia804a5c0[dwEAX];
dwECX += dwEAX;
dwEDX++;
}
dwEBP12 = dwEAX;
if ((dwEDX != 0x0F) || (dwECX != dwEBP16))
explode_bomb();
return dwEAX;
}
//Conclusion: If you want the function phase_5() to succeed then the values of the
//important registers need the following values (context beginning at 8048f3c till the end):
//EAX==0x0F && EDX!=0x0F && ECX!=dwEBP16
//Since ECX and EDX get changed inside the loop it all depends on the array element value at a certain position
http://pastebin.com/7BMrsuuP
Ich kann natürlich auch was falsch interpretiert haben, bin gerade nicht so konzentriert...
Gruß