2013-04-26 2 views
0

Я декомпилировал dll, и я хочу заменить вызов функции в DLL с вызовом, созданным мной (с той же подписью).Замена функции в декомпилированной DLL

Мне удалось найти, где функция вызывается в сборке. Может ли кто-нибудь объяснить, что мне теперь нужно делать?

Может ли моя пользовательская функция быть расположена в отдельной DLL или она должна быть включена в одну и ту же DLL?

Как я могу назвать функцию вызова функции моей новой?

Thanks

+1

Возможно, вам будет проще просто запланировать DLL. Добавьте новый код в конец текстового сегмента и переместите его в добавленный код в начале старой функции. –

+0

На самом деле я просто понял, что это не вариант. Он должен перейти или вызвать функцию из другой dll. Это возможно? – Lukesmith

+0

Если вы можете обновить свой вопрос с помощью дополнительных _details_, как вы хотите вызвать функцию из внешней DLL, я обновлю свой ответ, чтобы отразить изменения. –

ответ

3

Может быть проще просто исправить исполняемый модуль. Добавьте новый код в конец текстового сегмента и переместите его в добавленный код в начале старой функции. Таким образом, вам не придется решать проблемы, которые может вызвать декомпиляционная версия DLL.

Например вот начало существующей функции вы хотите заменить:

000D0880 push  ebp 
000D0881 mov   ebp,esp 
000D0883 sub   esp,0E0h 
000D0889 push  ebx 
000D088A push  esi 
000D088B push  edi 
000D088C lea   edi,[ebp-0E0h] 
000D0892 mov   ecx,38h 
000D0897 mov   eax,0CCCCCCCCh 

Чтобы перенаправить вызов просто добавить инструкцию JMP на D0880. Мы добавляем инструкции NOP после прыжка, чтобы сделать дизассемблированный очиститель вывода во время сеансов отладки. Это не обязательно, но это пригодится.

000D0880 jmp   NewFunction 
000D0885 nop 
000D0886 nop 
000D0887 nop 
000D0888 nop 
000D0889 push  ebx 
000D088A push  esi 
000D088B push  edi 

Теперь вы добавить новый код в конец текстового сегмента и вычислить адрес на основе смещения, когда сегмент загружается. Это значительно облегчает отладку и управление, поскольку вы заранее знаете, где именно в текстовом сегменте находится ваша функция.

Для вызова любой функции из другого исполняемого модуля в процессе работы также можно выполнить. Поскольку вы уже знаете смещения как исходной функции, так и следующей функции, вы можете рассчитать их точное местоположение на основе адреса загрузки модуля.

typedef void (*EXTPROC)(int a, int b); 

// Windows loads the dll at 0xC0000 
HMODULE hMod = LoadLibrary("some.dll"); 
// The function is at offset 0x10880 (from start of text segment) 
EXTPROC proc = CalculateAddress(hMod, 0x00010880); 
// Call proc at 0xd0880 
proc(0, 1); 

Функция CalculateAddress извлекает базовый адрес DLL и вычисляет фактический адрес функции и возвращает указатель на него. Результат такой же, как в предыдущем примере - 0xD0880. Теперь, когда у вас есть адрес, вы можете вызвать его через указатель функции. Вы можете применить тот же метод для вызова новой функции, которую вы добавляете, так как вы знаете смещение этой функции.

Если вы хотите пройти лишнюю милю, вы можете даже обновить таблицу экспорта новыми позициями, указывающими на эти смещения, и использовать GetProcAddress для извлечения адреса без необходимости его вычисления. Это немного усложняет процесс исправления, поскольку вам необходимо обновить дополнительный раздел в DLL.

Чтобы вызвать функцию, существующую в другой DLL, является более сложной задачей, так как вам потребуется выполнить временную палитку исходной функции, чтобы вызвать ее адрес внешнего. Для этого я рекомендую изучить предложение, сделанное в Rich, и создать прокси-библиотеку DLL, как описано в статье this.

+0

Хороший ответ, но я просто понял, что мне действительно нужна другая функция, которая будет в другая dll. Есть ли способ, которым я мог бы заплатить при вызове функции в другой dll? – Lukesmith

+0

Я расширил ответ для вызова из функций из внешней DLL, а также с помощью прокси-библиотеки DLL для вызова функции во внешнем модуле (спасибо Rich за предложение!) –

+0

Чувак отвратительный ответ. Не могли бы вы объяснить, как я могу редактировать таблицу экспорта? Кажется, что это может быть легко, так как я могу добавить функцию, которую меня интересует в таблицу экспорта, а затем получить доступ к ней извне. – Lukesmith