Я понимаю, что этот вопрос довольно старый, но shf301 имеет правильную идею здесь. Единственное, что я хотел бы добавить, это реализовать поиск по шаблону в целевой библиотеке. Если у вас есть IDA или OllyDbg , вы можете найти функцию и просмотреть двоичные / шестнадцатеричные данные, которые окружают начальный адрес этой функции.
В большинстве случаев будет какая-то двоичная сигнатура, которая редко изменяется. В подписи могут содержаться подстановочные знаки, которые могут меняться между сборками, но в конечном итоге при поиске этого шаблона должен быть хотя бы один успешный удар, если только между сборками не произошло чрезвычайно резких изменений (в этот момент вы можете просто определить новую подпись для этой сборки). конкретная версия).
Способ, которым вы реализуете поиск по двоичному шаблону, выглядит так:
bool bCompare(const PBYTE pData, const PBYTE bMask, const PCHAR szMask)
{
for(;*szMask;++szMask,++pData,++bMask)
if(*szMask=='x' && *pData!=*bMask)
return 0;
return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwAddress, DWORD dwLen, PBYTE bMask, PCHAR szMask)
{
for(DWORD i=0; i<dwLen; i++)
if (bCompare((PBYTE)(dwAddress+i),bMask,szMask))
return (DWORD)(dwAddress+i);
return 0;
}
Пример использования:
typedef void (*UnExportedFunc)();
//...
void CallUnExportedFunc()
{
// This will get the DLL base address (which can vary)
HMODULE hMod = GetModuleHandleA( "My.dll" );
// Get module info
MODULEINFO modinfo = { NULL, };
GetModuleInformation( GetCurrentProcess(), hMod, &modinfo, sizeof(modinfo) );
// This will search the module for the address of a given signature
DWORD dwAddress = FindPattern(
hMod, modinfo.SizeOfImage,
(PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86",
"xx????xx????xx"
);
// Calculate the acutal address
DWORD_PTR funcAddress = (DWORD_PTR)hMod + dwAddress;
// Cast the address to a function poniter
UnExportedFunc func = (UnExportedFunc)funcAddress;
// Call the function
func();
}
Это работает путем передачи базового адреса загруженной библиотеки через GetModuleHandle
, указания длины (в байтах) для поиска, двоичных данных для поиска и маски, которая указывает, какие байты двоичной строки являются действительный ('x') и которые должны быть пропущены ('?'). Затем функция будет проходить через область памяти загруженного модуля в поисках совпадения. В некоторых случаях может быть более одного совпадения, и в этом случае имеет смысл сделать вашу подпись чуть более выраженной, чтобы там было только одно совпадение.
Опять же, вам необходимо выполнить начальный двоичный поиск в приложении для разборки, чтобы узнать, что это за сигнатура, но как только вы это сделаете, этот метод должен работать немного лучше, чем ручной поиск смещения функции время цель построена. Надеюсь, это поможет.