A Complete Example

[Previous] [Next]

Now that I've covered all the important parts of Intel assembly language, I want to show a complete example of a Win32 API function before turning to the Disassembly window. Listing 6-2 shows the completely commented disassembly of the lstrcpyA function from the Windows NT 4 Service Pack 4 KERNEL32.DLL. The lstrcpyA function copies one string into another string. I chose this function because it shows a little bit of everything that I've discussed so far in this chapter and because the purpose of the function is easily understood. I made the comments, delineated by semicolons, as detailed as possible.

Listing 6-2 IstrcpyA—A complete assembly-language example

; Function prototype: ; LPTSTR lstrcpy ( LPTSTR lpString1 , LPCTSTR lpString2 ) lstrcpyA: ; Start preparing to set up an SEH frame. 77F127E6: MOV EAX , FS:[00000000h] ; Do the regular stack frame setup. 77F127EC: PUSH EBP 77F127ED: MOV EBP , ESP ; Continue with the SEH frame setup. 77F127EF: PUSH 0FFh 77F127F1: PUSH 77F3CD48h 77F127F6: PUSH _except_handler3 77F127FB: PUSH EAX 77F127FC: MOV DWORD PTR FS:[00000000h] , ESP ; Save 12 bytes for local variables. 77F12803: SUB ESP , 00Ch ; Save register values that will be destroyed as part of this function. 77F12806: PUSH EBX 77F12807: PUSH ESI 77F12808: PUSH EDI ; Save the current top of the stack into a local variable. This ; line is part of the SEH setup as well. 77F12809: MOV DWORD PTR [EBP-018h] , ESP ; Initialize this local variable to 0. This line indicates that the ; function is entering the __try block. 77F1280C: MOV DWORD PTR [EBP-004h] , 00000000h ; The first step after setting up is to get the length of the string to ; copy. The string to copy is the second parameter. ; Move the second parameter, the string to be copied, into EDI. 77F12813: MOV EDI , DWORD PTR [EBP+00Ch] ; lstrcpy will look through 4,294,967,295 bytes for the NULL terminator. ; EDX is used later with a value of _1, so it's initialized here. ; Remember that ECX is what REPNE SCAS uses to count the loop. 77F12816: MOV EDX , FFFFFFFFh 77F1281B: MOV ECX , EDX ; Zero out EAX so that SCAS will look for the NULL character. 77F1281D: SUB EAX , EAX ; Look for the NULL character. 77F1281F: REPNE SCAS BYTE PTR [EDI] ; Because ECX is counted down, switch all the bits so that the length of ; the string is in ECX. The length here includes the NULL character. 77F12821: NOT ECX ; Because the REPNE SCAS also incremented EDI, subtract the length of the ; string from EDI so that EDI points back to the start of the string. 77F12823: SUB EDI , ECX ; Hold the string length in EAX. 77F12825: MOV EAX , ECX ; Move the second parameter into ESI since ESI is the source operand for ; the string instructions. 77F12827: MOV ESI , EDI ; Move the first parameter, the destination string, into EDI. 77F12829: MOV EDI , DWORD PTR [EBP+008h] ; The string length was counted in bytes. Divide the string length by ; 4 to get the number of DWORDs. If the number of characters is odd, ; the REPE MOVS won't copy them all. Any remaining bytes are copied ; right after the REPE MOVS. 77F1282C: shr ECX , 002h ; Copy the second parameter string into the first parameter string. 77F1282F: REPE MOVS DWORD PTR [EDI] , DWORD PTR [ESI] ; Move the saved string length into ECX. 77F12831: MOV ECX , EAX ; AND the count with 3 to get the remaining bytes to copy. 77F12833: AND ECX , 003h ; Copy the remaining bytes from string to string. 77F12836: REPE MOVS BYTE PTR [EDI] , BYTE PTR [ESI] ; lstrcpy returns the first parameter, so move the return value ; into EAX. 77F12838: MOV EAX , DWORD PTR [EBP+008h] ; Set the local variable to _1, which indicates that the function is ; leaving this try/except block. 77F1283B: MOV DWORD PTR [EBP-004h] , EDX ; The function has completed; jump out and move home. 77F1283E: JMP 77F12852h ; If you look through this function, you'll notice that no instruction ; actually jumps or branches to 0x77F12840. This address is the ; exception filter part of the SEH. The exception filter is a piece of ; code that tells the SEH unwinding what to do. The exception filter here ; is equivalent to __except ( EXCEPTION_EXECUTE_HANDLER ). The unwinding ; code should execute the handler, which is the code right after the RET ; instruction. To learn more about exception filters, see MSDN or ; Jeffrey Richter's "Programming Applications for Microsoft Windows" ; (Microsoft Press, 1999). 77F12840: MOV EAX , 00000001h 77F12845: RET ; The next three instructions are the exception block for the function. ; Restore the stack saved earlier. 77F12846: MOV ESP , DWORD PTR [EBP-018h] ; Set the local variable to _1, which indicates that the function is ; leaving this try/except block. 77F12849: MOV DWORD PTR [EBP-004h] , FFFFFFFFh ; Set up to return 0, the bad return value. 77F12850: XOR EAX , EAX ; Get the previous SEH frame. 77F12852: MOV ECX , DWORD PTR [EBP-010h] ; Restore the previously pushed EDI. 77F12855: POP EDI ; Undo the SEH frame. 77F12856: MOV DWORD PTR FS:[00000000h] , ECX ; Restore the previously pushed ESI. 77F1285D: POP ESI ; Restore the previously pushed EBI. 77F1285E: POP EBX ; Undo the normal stack frame setup. 77F1285F: MOV ESP , EBP 77F12861: POP EBP ; Return to the caller and clean off 8 bytes from the stack. ; lstrcpy is a __sdtcall function. 77F12862: RET 00008h 



Debugging Applications
Debugging Applications for MicrosoftВ® .NET and Microsoft WindowsВ® (Pro-Developer)
ISBN: 0735615365
EAN: 2147483647
Year: 2000
Pages: 122
Authors: John Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net