Python3 использует restype для определения возвращаемого значения kernel32.GetModuleHandleA, но значение вывода Python очень велико

1

Я изучаю книгу "Python Grey Hat", это одна из моих функций, я долго искал эту проблему или не решался.

def func_resolve(self,dll,function):
    GetModuleHandle             = kernel32.GetModuleHandleA
    GetModuleHandle.argtypes    = [c_char_p]
    GetModuleHandle.restype     = c_void_p
    handle = GetModuleHandle(dll)
    print(handle)
    GetProcAddress              = kernel32.GetProcAddress
    GetProcAddress.argtypes     = [c_void_p,c_char_p]
    GetProcAddress.restype      = c_void_p
    address = GetProcAddress(handle,function)
    print(address)

Мое значение дескриптора вывода - 140707194077184, значение адреса - 140707194386736 Я использую OllyDbg для просмотра адреса функции wprintf в msvcrt.dll, является 0x73D178A0, но значение адреса преобразуется в шестнадцатеричное, также намного больше, чем 0x73D178A0, надеюсь, что кто-то может помоги мне, спасибо

  • 0
    Можете ли вы указать полный путь к msvcrt.dll ?
  • 0
    К вашему сведению, вы должны использовать GetModuleHandleW с Unicode c_wchar_p , особенно в Python 3, где строки являются Unicode. Кроме того, вы должны определять прототипы только один раз для указателей на функции kernel32 , а не каждый раз, когда вы вызываете func_resolve . Это работает, потому что когда вы в первый раз просматриваете атрибут GetModuleHandleW в kernel32 , он кэширует созданный объект-указатель функции, поэтому при последующем доступе используется тот же объект.
Показать ещё 2 комментария
Теги:
ctypes

2 ответа

2

Никогда не отвечая на мой комментарий, я нашел причину. От OllyDbg (акцент мой):

OllyDbg - это 32-разрядный ассемблер, анализирующий отладчик для Microsoft Windows .

Это означает, что он может загружать (работать с) 32-битные процессы (и/или DLL) только. Адрес wprintf подтверждает это (0x 73D178A0 - 32 бит, поскольку он имеет (самое большее) 8 шестнадцатеричных цифр).

С другой стороны, в Python вы получаете (намного) большие значения для указателей или адресов (например, handler = 140707194077184 (0x 7FF8F256B930)), которые не соответствуют 32-битовому диапазону, поэтому 64 бит. Для получения дополнительной информации о том, как запустить Python-архитектуру, проверьте [SO]: Как определить, выполняется ли моя оболочка python в 32-битном или 64-битном режиме на OS X? (Ответ @CristiFati) (даже если вопрос касается OSX, Win также покрывается).

Итак, какой улов? Это [MS.Docs]: редиректор файловой системы, который смутил вас в отношении msvcr (t ###). Dll location:

  • Python (64 бит) загрузил его из "% windir%\System32 "
  • OllyDbg (32 бит) заставил вас подумать, что он загрузил его из того же места (для соображений обратной совместимости), когда он загрузил его с "% windir%\SysWOW64 ",

Используя инструмент, созданный для 32-разрядных и 64-битных, которые вы можете запускать параллельно (я использую Dependency Walker), вы можете увидеть различия.

  • 0
    Мой Windows10, мой загруженный Python3 является 32-разрядным
  • 0
    Это распространенная ошибка. Действительно проверьте мой ответ.
Показать ещё 4 комментария
1

Возвращаемое значение - дескриптор Windows. Значение большое, потому что вы используете 64-битный Python. Значение не имеет значения, если вы правильно указали свои ctypes. Этот код будет работать Python 2 или 3, 32- или 64-бит:

from __future__ import print_function
import sys
from ctypes import *

print(sys.version)

kernel32 = WinDLL('kernel32')

GetModuleHandle          = kernel32.GetModuleHandleW
GetModuleHandle.argtypes = [c_wchar_p]
GetModuleHandle.restype  = c_void_p
GetProcAddress           = kernel32.GetProcAddress
GetProcAddress.argtypes  = [c_void_p,c_char_p]
GetProcAddress.restype   = c_void_p

handle = GetModuleHandle(u'user32')
address = GetProcAddress(handle,b'MessageBeep')
print(hex(address))
MessageBeep = WINFUNCTYPE(c_int,c_uint)(address)
MessageBeep(0)

Выход с двумя Pythons, которые я установил (звуковой сигнал воспроизводится каждый раз):

C:\>py -2 test.py
2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)]
0x756e56d0

C:\>py -3 test.py
3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)]
0x7fff6ca29a40
  • 0
    Прочитав ваш пример и вывод, я снова посмотрел на свой python3 и обнаружил, что был неправ. Оказывается, мой python3 64-битный. Я виню меня за осторожность. Если я вижу win32, я думаю, что это 32-разрядная версия. Спасибо.
  • 0
    Пожалуйста. Upvotes == Спасибо: ^)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню