-
Notifications
You must be signed in to change notification settings - Fork 73
Test Example
We have included a few test binaries along with the Binee repository. These are located in the tests
folder in the Binee project root. This example will cover the basic functionality of Binee. All examples leverage the Docker container included with the project and outlined in the Setup section.
Running Binee with no options aside from the file name will only print function calls:
root@b5a411b1b3da:~/go/src/binee# ./binee tests/ConsoleApplication1_x86.exe
[1] 0x200250b0: F GetSystemTimeAsFileTime(lpSystemTimeAsFileTime = 0xb7feffe0) = 0xb7feffe0
[1] 0x2001eb40: P GetCurrentThreadId() = 0x0
[1] 0x2002c8d0: P GetCurrentProcessId() = 0x2001
[1] 0x203e9f30: P GetCurrentProcessId() = 0x2001
[1] 0x2001eb50: F QueryPerformanceCounter(lpPerformanceCount = 0xb7feffd8) = 0x1
[1] 0x20025500: F IsProcessorFeaturePresent(ProcessorFeature = 0xa) = 0x1
[1] 0x20dc4570: F _initterm_e(PVFV = 0x4020d8, PVFV = 0x4020e4) = 0x0
[1] 0x20dc4970: F _initterm(PVPV = 0x4020cc, PVPV = 0x4020d4) = 0x0
[1] 0x20dd3980: F __p___argv() = 0x7ffe000a
[1] 0x20dce6f0: F __p___argc() = 0x7ffe0000
[1] 0x20dd3c50: F _get_initial_narrow_environment() = 0x7ffe0000
[1] 0x20dc10a0: P __acrt_iob_func() = 0x5d2ceba0
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'GENERIC_READ = 0x%llx\n', p0 = 0x80000000) = 0x403380
[1] 0x20dc10a0: P __acrt_iob_func() = 0x403380
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'GENERIC_WRITE = 0x%llx\n', p0 = 0x40000000) = 0x403380
[1] 0x20dc10a0: P __acrt_iob_func() = 0x403380
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'INVALID_HANDLE = 0x%llx\n', p0 = 0xffffffff) = 0x403380
[1] 0x20dc10a0: P __acrt_iob_func() = 0x1
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'CREATE_ALWAYS = 0x%x\n', p0 = 0x2) = 0x403380
[1] 0x20dc10a0: P __acrt_iob_func() = 0x403380
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'FILE_ATTRIBUTE_NORMAL = 0x%x\n', p0 = 0x80) = 0x403380
[1] 0x20dc10a0: P __acrt_iob_func() = 0x403380
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'ERROR_SUCCESS = 0x%x\n', p0 = 0x0) = 0x403380
[1] 0x2002cb80: F CreateFileA(lpFileName = 'malfile.exe', dwDesiredAccess = 0xc0000000, dwShareMode = 0x0, lpSecurityAttributes = 0x0, dwCreationDisposition = 0x2, dwFlagsAndAttributes = 0x80, hTemplateFile = 0x0) = 0xa00007b6
[1] 0x20084fbe: F VerSetConditionMask() = 0xa00007b6
[1] 0x20dc10a0: P __acrt_iob_func() = 0xa00007b6
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'out = 0x%x\n', p0 = 0xa00007b6) = 0x403380
[1] 0x20084fbe: F VerSetConditionMask() = 0x403380
[1] 0x20dc10a0: P __acrt_iob_func() = 0x403380
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'out = 0x%x\n', p0 = 0x403380) = 0x403380
[1] 0x20084fbe: F VerSetConditionMask() = 0x403380
[1] 0x20dc10a0: P __acrt_iob_func() = 0x403380
[1] 0x20dd0710: F __stdio_common_vfprintf(stream = 0x0, format = 'out = 0x%x\n', p0 = 0x403380) = 0x403380
[1] 0x21bc0780: P memset(dest = 0xb7feff1c, char = 0x0, count = 0x58) = 0xb7feff1c
[1] 0x2002d000: F WriteFile(hFile = 0xa00007b6, lpBuffer = 0xb7feff10, nNumberOfBytesToWrite = 0xb, lpNumberOfBytesWritten = 0xb7feff0c, lpOverlapped = 0x0) = 0xb
[1] 0x20025500: F IsProcessorFeaturePresent(ProcessorFeature = 0x17) = 0x1
[1] 0x20028ef0: F SetUnhandledExceptionFilter(lpTopLevelExceptionFilter = 0x0) = 0x4
[1] 0x20040950: F UnhandledExceptionFilter(ExceptionInfo = 0x402100) = 0x1
[1] 0x2002c8c0: P GetCurrentProcess() = 0x1
[1] 0x203edcb0: P GetCurrentProcess() = 0x1
[1] 0x20029690: F TerminateProcess(hProcess = 0xffffffff, uExitCode = 0xc0000409) = 0xffffffff
The format can be read as follows:
[Thread #] <address of call>: <Full/Partial hook (F/P)> <FunctionName>(arg1 = value1...) = <return value>
Do note that due to the nature of how we are hooking function calls, functions that are fully hooked show the proper return value. For unhooked or partial hooks, the return value is a lagging indicator and may show up in a later function call return value place.
Any Function Name
with **
around it indicates an unhooked function, and may need to be added to Binee's hook system.
Binee can also print every instruction (including function calls as outlined above) during its emulation.
[1] 0x0040142d: call 0x3f4
[1] 0x00401821: mov ecx, dword ptr [0x403000]
[1] 0x00401827: push esi
[1] 0x00401828: push edi
[1] 0x00401829: mov edi, 0xbb40e64e
[1] 0x0040182e: mov esi, 0xffff0000
[1] 0x00401833: cmp ecx, edi
[1] 0x00401835: je 6
[1] 0x0040183b: call 0xffffff97
[1] 0x004017d2: push ebp
[1] 0x004017d3: mov ebp, esp
[1] 0x004017d5: sub esp, 0x14
[1] 0x004017d8: and dword ptr [ebp - 0xc], 0
[1] 0x004017dc: lea eax, [ebp - 0xc]
[1] 0x004017df: and dword ptr [ebp - 8], 0
[1] 0x004017e3: push eax
[1] 0x004017e4: call dword ptr [0x402014]
[1] 0x2190c0b0: F GetSystemTimeAsFileTime(lpSystemTimeAsFileTime = 0xb7feffe0) = 0xb7feffe0
[1] 0x004017ea: mov eax, dword ptr [ebp - 8]
[1] 0x004017ed: xor eax, dword ptr [ebp - 0xc]
...
[1] 0x0040152e: pop eax
[1] 0x0040152f: imul eax, eax, 0
[1] 0x00401532: mov ecx, dword ptr [0x403000]
[1] 0x00401538: mov dword ptr [ebp + eax - 8], ecx
[1] 0x0040153c: push 4
[1] 0x0040153e: pop eax
[1] 0x0040153f: shl eax, 0
[1] 0x00401542: mov ecx, dword ptr [0x403004]
[1] 0x00401548: mov dword ptr [ebp + eax - 8], ecx
[1] 0x0040154c: push 0x402100
[1] 0x00401551: call 0xfffffee6
[1] 0x00401437: push ebp
[1] 0x00401438: mov ebp, esp
[1] 0x0040143a: push 0
[1] 0x0040143c: call dword ptr [0x402030]
[1] 0x2190fef0: F SetUnhandledExceptionFilter(lpTopLevelExceptionFilter = 0x0) = 0x4
[1] 0x00401442: push dword ptr [ebp + 8]
[1] 0x00401445: call dword ptr [0x402034]
[1] 0x21927950: F UnhandledExceptionFilter(ExceptionInfo = 0x402100) = 0x1
[1] 0x0040144b: push 0xc0000409
[1] 0x00401450: call dword ptr [0x40202c]
[1] 0x219138c0: P GetCurrentProcess() = 0x1
[1] 0x20122cb0: P GetCurrentProcess() = 0x1
[1] 0x20122cb3: ret
[1] 0x00401456: push eax
[1] 0x00401457: call dword ptr [0x402028]
[1] 0x21910690: F TerminateProcess(hProcess = 0xffffffff, uExitCode = 0xc0000409) = 0xffffffff
Binee's verbose mode can also print out the registers and parts of the stack along with each instruction.
---
eax --> 0xb0010000 = 0x0
ebx --> 0x00000000
ecx --> 0x0040142d
edx --> 0x0040142d
edi --> 0x0040142d
esi --> 0x0040142d
ebp --> 0xb0010000 = 0x0
esp --> 0xb7ff0000 = 0x0
eip --> 0x0040142d
0xb7ff0028 = 0x0
0xb7ff0024 = 0x0
0xb7ff0020 = 0x0
0xb7ff001c = 0x0
0xb7ff0018 = 0x0
0xb7ff0014 = 0x0
0xb7ff0010 = 0x0
0xb7ff000c = 0x0
0xb7ff0008 = 0x0
0xb7ff0004 = 0x0
esp --> 0xb7ff0000 = 0x0
0xb7fefffc = 0x0
0xb7fefff8 = 0x0
0xb7fefff4 = 0x0
0xb7fefff0 = 0x0
0xb7feffec = 0x0
0xb7feffe8 = 0x0
0xb7feffe4 = 0x0
0xb7feffe0 = 0x0
0xb7feffdc = 0x0
0xb7feffd8 = 0x0
[1] 0x0040142d: call 0x3f4
---
eax --> 0xb0010000 = 0x0
ebx --> 0x00000000
ecx --> 0x0040142d
edx --> 0x0040142d
edi --> 0x0040142d
esi --> 0x0040142d
ebp --> 0xb0010000 = 0x0
esp --> 0xb7fefffc = 0x401432
eip --> 0x00401821
0xb7ff0024 = 0x0
0xb7ff0020 = 0x0
0xb7ff001c = 0x0
0xb7ff0018 = 0x0
0xb7ff0014 = 0x0
0xb7ff0010 = 0x0
0xb7ff000c = 0x0
0xb7ff0008 = 0x0
0xb7ff0004 = 0x0
0xb7ff0000 = 0x0
esp --> 0xb7fefffc = 0x401432
0xb7fefff8 = 0x0
0xb7fefff4 = 0x0
0xb7fefff0 = 0x0
0xb7feffec = 0x0
0xb7feffe8 = 0x0
0xb7feffe4 = 0x0
0xb7feffe0 = 0x0
0xb7feffdc = 0x0
0xb7feffd8 = 0x0
0xb7feffd4 = 0x0
[1] 0x00401821: mov ecx, dword ptr [0x403000]
...
---
eax --> 0xffffffff
ebx --> 0x00000020
ecx --> 0x152c8d18
edx --> 0xb7feff11 = 0x206c6c65
edi --> 0x00403380
esi --> 0xb0000000 = 0x0
ebp --> 0xb7fefbcc = 0xb7fefefc
esp --> 0xb7fefbc0 = 0x40145d
eip --> 0x2196d690
0xb7fefbe8 = 0x0
0xb7fefbe4 = 0x0
0xb7fefbe0 = 0x0
0xb7fefbdc = 0x0
0xb7fefbd8 = 0x0
0xb7fefbd4 = 0x402100
0xb7fefbd0 = 0x401556
0xb7fefbcc = 0xb7fefefc
0xb7fefbc8 = 0xc0000409
0xb7fefbc4 = 0xffffffff
esp --> 0xb7fefbc0 = 0x40145d
0xb7fefbbc = 0x0
0xb7fefbb8 = 0x0
0xb7fefbb4 = 0x0
0xb7fefbb0 = 0x0
0xb7fefbac = 0x0
0xb7fefba8 = 0x0
0xb7fefba4 = 0x0
0xb7fefba0 = 0x0
0xb7fefb9c = 0x0
0xb7fefb98 = 0x0
[1] 0x2196d690: F TerminateProcess(hProcess = 0xffffffff, uExitCode = 0xc0000409) = 0xffffffff
Binee is able to resolve the mapping of Windows apisets to their proper DLL. This is functionality added by Microsoft in Windows 8. To show all mappings, derived from apisetschema.dll in System32:
root@b5a411b1b3da:~/go/src/binee# ./binee -A
api-ms-win-core-processtopology-obsolete-l1-1 [kernel32.dll]
api-ms-win-security-credentials-l1-1 [sechost.dll]
api-ms-win-service-winsvc-l1-2 [sechost.dll]
ext-ms-win-deployment-productenumerator-l1-1 [productenumerator.dll]
ext-ms-win-hyperv-devicevirtualization-l1-1 []
ext-ms-win-shell-directory-l1-1 [windows.storage.dll]
api-ms-win-core-com-private-l1-1 [combase.dll]
ext-ms-win-hostactivitymanager-hostidstore-l1-1 [rmclient.dll]
ext-ms-win-msimg-draw-l1-1 [msimg32.dll]
ext-ms-win-casting-device-l1-1 []
api-ms-win-core-console-l3-1 [kernelbase.dll]
api-ms-win-deprecated-apis-advapi-l1-1 []
ext-ms-win-dwmapidxgi-ext-l1-1 [dwmapi.dll]
ext-ms-win-uxtheme-themes-l1-1 [uxtheme.dll]
api-ms-win-core-comm-l1-1 [kernelbase.dll]
ext-ms-win-networking-teredo-l1-1 [windows.networking.connectivity.dll]
ext-ms-win-profile-extender-l1-1 [userenv.dll]
ext-ms-win-rometadata-dispenser-l1-1 [rometadata.dll]
ext-ms-win-rtcore-ntuser-dc-access-l1-1 [user32.dll]
ext-ms-win-shell32-shellcom-l1-1 [windows.storage.dll]
...