Я работаю над 64-разрядной машиной Windows 7 (у меня есть admin privs).Win 64bit GetThreadContext возвращает нулевые регистры или код ошибки 0x57
Я использую Python 2.7 (64-разрядный) с PyDev ctypes для Eclipse, чтобы попробовать и прочитать значения регистров во всех потоках, связанных с определенным PID (пробовал оба PID процессов, работающих в режимах 64 и 32 бит) , но когда я это делаю, значения для регистров все нулевые. Когда я использую Wow64GetThreadContext
, вызов завершается с GetLastError
возвращения 0x00000057 («недопустимые параметры» в соответствии с MSDN)
прилагаю к процессу успешно, перечислить темы (через CreateToolhelp32Snapshot
), найти темы, которые принадлежат процессу с соответствующий PID и попытаться получить контекст потока. Вот мой код для открытия нить и получить контекст потока:
Открытие резьбы:
def open_thread(self, thread_id):
h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
Получение контекста:
def get_thread_context(self, thread_id = None, h_thread = None):
context = CONTEXT()
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
#alternatively, for 64
context64 = WOW64_CONTEXT()
context64.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
#Obtain a handle to the thread
if h_thread is None:
self.h_thread = self.open_thread(thread_id)
kernel32.SuspendThread(self.h_thread)
if kernel32.GetThreadContext(self.h_thread, byref(context)):
kernel32.ResumeThread(self.h_thread)
return context
else:
kernel32.ResumeThread(self.h_thread)
return False
Я называю этот код с помощью:
debugger.attach(int(pid))
#debugger.run()
list = debugger.enumerate_threads()
for thread in list:
thread_context = debugger.get_thread_context(thread)
if thread_context == False:
print "[*] Thread context is false..."
else:
print "[*] Dumping registers for thread ID: 0x%08x" % thread
print "[**] Eip: 0x%016x" % thread_context.Eip
print "[**] Esp: 0x%016x" % thread_context.Esp
print "[**] Ebp: 0x%016x" % thread_context.Ebp
print "[**] Eax: 0x%016x" % thread_context.Eax
print "[**] Ebx: 0x%016x" % thread_context.Ebx
print "[**] Ecx: 0x%016x" % thread_context.Ecx
print "[**] Edx: 0x%016x" % thread_context.Edx
print "[*] End DUMP"
debugger.detach()
Когда я запускаю этот код с помощью GetThreadContext
с помощью структуры CONTEXT, я получаю контекстный объект bac k для каждого потока, но значения регистра равны нулю.
Я попытался заменить GetThreadContext
с Wow64GetThreadContext
(и, соответственно, SuspendThread
с Wow64SuspendThread
), но когда я делаю это, то вызов с ошибкой "неправильными параметрами. Аргументы, которые я даю Wow64GetThreadContext
, являются такими же, как те, которые я даю GetThreadContext
, кроме имени переменных в предоставленном мной коде (это потому, что когда я смотрел их определения в WinNT.h, они были эквивалентными (если только я не пропустил . что-то) я определил эти структуры следующим образом:
class WOW64_CONTEXT(Structure):
_fields_ = [
("ContextFlags", DWORD),
("Dr0", DWORD),
("Dr1", DWORD),
("Dr2", DWORD),
("Dr3", DWORD),
("Dr6", DWORD),
("Dr7", DWORD),
("FloatSave", WOW64_FLOATING_SAVE_AREA),
("SegGs", DWORD),
("SegFs", DWORD),
("SegEs", DWORD),
("SegDs", DWORD),
("Edi", DWORD),
("Esi", DWORD),
("Ebx", DWORD),
("Edx", DWORD),
("Ecx", DWORD),
("Eax", DWORD),
("Ebp", DWORD),
("Eip", DWORD),
("SegCs", DWORD),
("EFlags", DWORD),
("Esp", DWORD),
("SegSs", DWORD),
("ExtendedRegisters", BYTE * 512),
]
class WOW64_FLOATING_SAVE_AREA(Structure):
_fields_ = [
("ControlWord", DWORD),
("StatusWord", DWORD),
("TagWord", DWORD),
("ErrorOffset", DWORD),
("ErrorSelector", DWORD),
("DataOffset", DWORD),
("DataSelector", DWORD),
("RegisterArea", BYTE * 80),
("Cr0NpxState", DWORD),
]
class CONTEXT(Structure):
_fields_ = [
("ContextFlags", DWORD),
("Dr0", DWORD),
("Dr1", DWORD),
("Dr2", DWORD),
("Dr3", DWORD),
("Dr6", DWORD),
("Dr7", DWORD),
("FloatSave", FLOATING_SAVE_AREA),
("SegGs", DWORD),
("SegFs", DWORD),
("SegEs", DWORD),
("SegDs", DWORD),
("Edi", DWORD),
("Esi", DWORD),
("Ebx", DWORD),
("Edx", DWORD),
("Ecx", DWORD),
("Eax", DWORD),
("Ebp", DWORD),
("Eip", DWORD),
("SegCs", DWORD),
("EFlags", DWORD),
("Esp", DWORD),
("SegSs", DWORD),
("ExtendedRegisters", BYTE * 512),
]
class FLOATING_SAVE_AREA(Structure):
_fields_ = [
("ControlWord", DWORD),
("StatusWord", DWORD),
("TagWord", DWORD),
("ErrorOffset", DWORD),
("ErrorSelector", DWORD),
("DataOffset", DWORD),
("DataSelector", DWORD),
("RegisterArea", BYTE * 80),
("Cr0NpxState", DWORD),
]
Я сделал изрядное количество прибегая к помощи по этому вопросу, и попытался следующие без толку:
Согласно к комментарию по MSDN:
CONTEXT_FULL
должно бытьCONTEXT_AMD64 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT
для корректной работы с Win64.Я попытался переименования регистров в моем КОНТЕКСТЕ и WOW_64CONTEXT структуры, заменив «E» в названиях регистров с «R» (EAX -> Ракс и т.д.)
Кто-нибудь еще использовал Python с ctypes, чтобы успешно получить контекст 64-разрядного потока в Windows?
@cghlke Да, я просто попробовал это безрезультатно. Я все еще вижу коды ошибок 0x57. – bl4ckmes4
http://go4answers.webhost4life.com/Example/visual-studio-2010-101539.aspx: результат google (0x57 = 87), показывающий, что это вряд ли связано с Python –
Согласен. Кто-нибудь знает, как разрешить это, или если что-то с вышеприведенным кодом неверно/неполно? – bl4ckmes4