Skip to content

incorrect execution of GetLastError, wrong set of assembly instructions executed #44

Description

@mewmew

I was running binee last night, and on one of my samples the invocation of GetLastError would result in incorrect execution (eventually resulting in an invalid read).

I used IDA to verify the implementation of GetLastError, and for some reason, binee is executing another set of assembly instructions, rather than the actual assembly instructions of the GetLastError function (as present in kernel32.dll).

To help troubleshoot, I've created a minimal test case (b.exe). Find source code, build instructions and binary attached below.

extern _SetLastError@4
extern _GetLastError@0
extern _ExitProcess@4

global _main

[section .text]

_main:
	push 42
	call _SetLastError@4
	call _GetLastError@0
	push eax
	call _ExitProcess@4
# assemble b.asm into 32-bit PE object file.
$ nasm -f win32 -o b.obj b.asm

# link object file with kernel32.lib to create executable
$ wine ~/VS6/VC98/Bin/LINK.EXE /OUT:b.exe /ENTRY:main /subsystem:console /machine:i386 /LIBPATH:${HOME}/VS6/VC98/LIB /nologo b.obj kernel32.lib

# run binary to check result of GetLastError
$ wine b.exe ; echo $?
42

Results of running binee on b.exe:

$ ~/Desktop/binee/binee -v -d -c win.yaml b.exe
[1] 0x00401000: push 0x2a
[1] 0x00401002: call 0x10
[1] 0x00401012: jmp dword ptr [0x402008]
[1] 0x2025e2d3: F kernel32.dll:SetLastError(dwErrCode = 0x2a) = 0xb0010000
[1] 0x00401007: call 0x11
[1] 0x00401018: jmp dword ptr [0x402000]
[1] 0x2025e0bf: P kernel32.dll:GetLastError() = 0xb0010000
[1] 0x2025e0bf: dec esi
[1] 0x2025e0c0: push esp
[1] 0x2025e0c1: inc esp
[1] 0x2025e0c2: dec esp
[1] 0x2025e0c3: dec esp
[1] 0x2025e0c4: push edx
[1] 0x2025e0c6: je 0x6e
[1] 0x2025e0c8: inc edi
[1] 0x2025e0c9: je 0x4f
[1] 0x2025e0cc: popal 
[1] 0x2025e0cd: jae 0x76
[1] 0x2025e143: je 0x4a
[1] 0x2025e145: popal 
[1] 0x2025e147: add byte ptr fs:[esi + 0x54], cl
[1] 0x2025e14b: inc esp
[1] 0x2025e14c: dec esp
[1] 0x2025e14d: dec esp
[1] 0x2025e14e: push edx
[1] 0x2025e150: je 0x6e
[1] 0x2025e152: dec ecx
[1] 0x2025e153: outsb dx, byte ptr [esi]
[1] 0x2025e154: je 0x67
[1] 0x2025e156: jb 0x6e
[1] 0x2025e158: outsd dx, dword ptr [esi]
[1] 0x2025e159: arpl word ptr [ebx + 0x65], bp
[1] 0x2025e15c: inc esi
[1] 0x2025e15e: insb byte ptr es:[edi], dx
[1] 0x2025e15f: jne 0x75
[1] 0x2025e1d4: push ecx
[1] 0x2025e1d5: jne 0x67
[1] 0x2025e23c: outsd dx, dword ptr [esi]
[1] 0x2025e23d: outsb dx, byte ptr [esi]
[1] 0x2025e23e: je 0x67
[1] 0x2025e240: js 0x76
[1] 0x2025e242: add byte ptr [esi + 0x54], cl
[1] 0x2025e245: inc esp
[1] 0x2025e246: dec esp
[1] 0x2025e247: dec esp
[1] 0x2025e248: push edx
[1] 0x2025e24a: je 0x6e
[1] 0x2025e24c: inc ebx
[1] 0x2025e24d: popal 
[1] 0x2025e24e: jo 0x76
[1] 0x2025e250: jne 0x74
[1] 0x2025e2c4: arpl word ptr [ecx + ebp*2 + 0x6f], si
[1] 0x2025e2c8: outsb dx, byte ptr [esi]
Invalid Read: address = 0xffffff00, size = 0x1, value = 0x0

Contents of win.yaml:

$ cat win.yaml
root: "/home/u/_share_/xp/

b.exe attachment: b.tar.gz

Reference disassembly of GetLastError from IDA:

.text:7C830759 ; DWORD __stdcall GetLastError()
.text:7C830759 _GetLastError@0 proc near               ; CODE XREF: GetComputerNameExW(x,x,x):loc_7C820174↑p
.text:7C830759                                         ; GetComputerNameExW(x,x,x):loc_7C82018B↑p ...
.text:7C830759                 mov     eax, large fs:18h
.text:7C83075F                 mov     eax, [eax+34h]
.text:7C830762                 retn
.text:7C830762 _GetLastError@0 endp

Edit: note that the return value of GetLastError reported by binee is incorrect ([1] 0x2025e0bf: P kernel32.dll:GetLastError() = 0xb0010000), it should be 0x2a not 0xb0010000). Furthermore, not that the first assembly instruction of GetLastError is reported by binee as [1] 0x2025e0bf: dec esi, but should be .text:7C830759 mov eax, large fs:18h.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions