Inspired by this answer about RE-ing IOCTLs, I tried to get the IOCTLs from
NtDeviceIoControlFile()
syscall. Here is an example of that syscall
in Beep()
function in KernelBase.dll
file:
- In x86_64 (__fastcall) Assembly language:
and [rsp+72], ebx ; OutputBufferLength
and [rsp+64], rbx ; OutputBuffer
mov dword ptr [rsp+56], 8 ; InputBufferLength
lea rax, [rsp+152]
mov [rsp+48], rax ; InputBuffer
mov dword ptr [rsp+40], 10000h ; IoControlCode
lea rax, [rsp+78h+var_18]
mov [rsp+32], rax ; IoStatusBlock
xor r9d, r9d ; ApcContext
xor r8d, r8d ; ApcRoutine
xor edx, edx ; Event
mov rcx, [rsp+144] ; FileHandle
call cs:__imp_NtDeviceIoControlFile
test eax, eax
- In C language:
NTSTATUS Status;
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
0x10000u,
&InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength);
I tried this code in IDA Python to list all the cross references of that syscall:
# Global arrays
XrefList = []
# Get imported function address
FuncAddr = LocByName("__imp_NtDeviceIoControlFile")
print "NtDeviceIoControlFile found at 0x%08x" % FuncAddr
# Iterate over all call references
for xref in XrefsTo(FuncAddr, True):
if xref.frm not in XrefList:
XrefList.append(xref.frm)
print "xref @ 0x%08x (%s)" % (xref.frm, GetFunctionName(xref.frm))
else:
continue
This code can successfully list all the syscall in a list. But I want to list
all the IOCTLs values at RSP+40
offset i.e. 6th parameter. What code should I add?
If you have any suggestion with IDC code I shall appreciate it as well.