Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

идентификация функции в дизассемблированном коде

26K
12 октября 2010 года
3D-GRAF
41 / / 28.06.2008
Здравствуйте, прошу помочь в решении проблемы, так как с ассемблером знаком больше по наслышке, а задачу надо выполнить как можно быстрей.
Как можно идентифицировать название функции?

Есть простенькая программа, выводящая MessageBox, исходник на ассемблере:
Код:
.586P
.MODEL FLAT,STDCALL
includelib f:\masm32\lib\user32.lib
EXTERN  MessageBoxA@16:NEAR
;сегмент данных
_DATA SEGMENT
TEXT1 DB 'No problem!',0
TEXT2 DB 'Message',0
_DATA ENDS
;сегмент кода
_TEXT SEGMENT
START:
    PUSH OFFSET 0
    PUSH OFFSET TEXT2
    PUSH OFFSET TEXT1
    PUSH 0
    CALL MessageBoxA@16
    RETN
_TEXT ENDS
END START


Пытаюсь дизассмеблировать с помощью dumpbin.exe (та, что в VC идет), получаю код:
 
Код:
00401000: push        0
  00401002: push        40300Ch
  00401007: push        403000h
  0040100C: push        0
  0040100E: call        00401014
  00401013: ret
  00401014: jmp         dword ptr ds:[00402000h]


Как можно понять, что call в данном случае вызывает MessageBoxA?
по адресу 00401014 у нас идет jmp на 00402000, а где можно найти этот адрес?

Заранее большое спасибо
8.2K
12 октября 2010 года
bagie2
299 / / 26.10.2008
по адресу 00402000h лежит адрес той самой USER32!MessageBoxA - это ячейка в табличке адресов импорта (IAT) и заполняет эти значения загрузчик исходя из содержимого директории импортов.

можно конечно сразу было в программе писать call 7E3A07EAh (для WinXP SP3), но на каждой системе адрес функций будет(может) отличаться поэтому импорты и придумали.

а call 00401014 + jmp это переходник, который делает компилятор

почитайте это или на русском

//а чтобы было сразу видно что и почем возьмите нормальный дизассемблер или в отладчике гоняйте
26K
16 октября 2010 года
3D-GRAF
41 / / 28.06.2008
Спасибо большое за ответ, но видимо я совсем деревянный :o
Смотрел через OllyDbg, но кое-что не понимаю, откуда она берет.
Чтобы лучше объяснить, приведу другой пример:

Код ассемблера:
Код:
.586P
.MODEL FLAT,STDCALL
includelib c:\masm32\lib\user32.lib
MessageBoxA PROTO      ,:DWORD, :DWORD, :DWORD, :DWORD
MessageBoxW PROTO      ,:DWORD, :DWORD, :DWORD, :DWORD
;сегмент данных
_DATA SEGMENT
TEXT1 DB 'TITLE',0
TEXT2 DB 'Hello World',0
_DATA ENDS
;сегмент констант
_CONST SEGMENT
NULL  equ 0
MB_OK equ 0
_CONST ENDS
;сегмент кода
_TEXT SEGMENT
START:
    INVOKE    MessageBoxA, NULL, ADDR TEXT1, ADDR TEXT2, MB_OK
    INVOKE    MessageBoxW, NULL, ADDR TEXT1, ADDR TEXT2, MB_OK
    RETN
_TEXT ENDS
END START


После дизассемблирования через dumpbin.exe (использую эту программку, потому что мне нужен консольный вывод, чтобы парсить его своей программой):

Код:
00401000: push        0
  00401002: push        403006h
  00401007: push        403000h
  0040100C: push        0
  0040100E: call        00401028
  00401013: push        0
  00401015: push        403006h
  0040101A: push        403000h
  0040101F: push        0
  00401021: call        0040102E
  00401026: ret
  00401027: int         3
  00401028: jmp         dword ptr ds:[00402004h]
  0040102E: jmp         dword ptr ds:[00402000h]


Соответствия получаются
jmp dword ptr ds:[00402004h] -> MessageBoxA
jmp dword ptr ds:[00402000h] -> MessageBoxW

Как на основании 00402004 и 00402000 вычислять имя функции? Если заглянуть в .rdata, то увидим:
 
Код:
00402000: 4E 20 00 00 40 20 00 00 00 00 00 00 34 20 00 00  N ..@ ......4 ..
  00402010: 00 00 00 00 00 00 00 00 5C 20 00 00 00 20 00 00  ........\ ... ..
  00402020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00402030: 00 00 00 00 4E 20 00 00 40 20 00 00 00 00 00 00  ....N ..@ ......
  00402040: B1 01 4D 65 73 73 61 67 65 42 6F 78 41 00 B8 01  ±.MessageBoxA.?.
  00402050: 4D 65 73 73 61 67 65 42 6F 78 57 00 75 73 65 72  MessageBoxW.user
  00402060: 33 32 2E 64 6C 6C 00 00                          32.dll..


Если в импортируемые библиотеки:
 
Код:
user32.dll
                402000 Import Address Table
                402034 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                  1B8 MessageBoxW
                  1B1 MessageBoxA


Ни .rdata, не импортируемые функции не дают мне понять, что же такое 00402004 и 00402000. Куда мне тыкнуться с ними, чтобы увидеть на какие функции осуществляется переход?
7
16 октября 2010 года
@pixo $oft
3.4K / / 20.09.2006
Почитай про PE-формат и всё сразу станет понятно.Сам давно не занимался,поэтому ничего особо посоветовать не могу.Можно почитать Microsoft'овский оригинал
26K
16 октября 2010 года
3D-GRAF
41 / / 28.06.2008
Да читал.. если бы сам понял, не стал бы спрашивать.
Вот и получается, то ли лыжи не едут, то ли я...
8.2K
16 октября 2010 года
bagie2
299 / / 26.10.2008
всё таки почитать по формату PE следовало бы.

по адресам 00402000h и 00402004h лежит RVA (Relative Virtual Address), который указывает на ASCIIZ-строку с двухбайтовым префиксом (hint) и содержит имя функции. но не всегда так будет, зависит от компилятора\линкера, все по разному импорты строят.

в данном случае:
по адресу 00402000h лежит DWORD - 0000204Eh - это RVA.
если теперь к нему прибавить 400000h (ImageBase) получим адрес 0040204Eh и теперь + 2 (отбросим hint) = 00402050 - указатель на строку MessageBoxW
260
16 октября 2010 года
Ramon
1.1K / / 16.08.2003
Цитата:
но не всегда так будет, зависит от компилятора\линкера, все по разному импорты строят.



А образ процесса формируется посредством черной магии, формат то неизвестен.

PS: Читаем про динамическое связывание и загрузку в антернетах

8.2K
16 октября 2010 года
bagie2
299 / / 26.10.2008
Ramon
Вы это к чему написали? И, пожалуйста, если уже начали, то внятно закончите и выразите что хотели этим сказать.

всё дело в том, что ImportLookUp (OriginalFirstThunk) (IMAGE_IMPORT_DIRECTORY+00h) может указывать на ту же самую табличку что и AddresTableRva (FirstThunk) (IMAGE_IMPORT_DIRECTORY+10h) или может быть 0x00000000 (что является аналогом) -в таком случае берем имена функций из AddresTableRva (IAT)
(IMAGE_IMPORT_DIRECTORY в примере идет по адресу - 0040200Ch)

либо ImportLookUp может указывать на отдельную табличку и тогда уже из неё берутся имена\ординалы, но адреса кладутся всё также в AddresTableRva. часто в таком варианте IAT уже заполняется какими-нибудь адресами верными для системы на которой происходила компиляция, но в момент загрузки они конечно же перезаписываются

да, формат описан, но собирать файлы мы можем довольно вариабельно, часто до всяких извращений доходит

и еще, я не обратил внимания сначала в примере что выше был
Import Address Table (AddresTableRva) и Import Name Table (ImportLookUp) - это две разные таблички, но с одинаковыми данными - это 3 DWORD: 0000204E, 00002040, 00000000 так что тут и так и так можно рассматривать

и если допустим заменить 402034 Import Name Table на 0 Import Name Table то программка как работала так и будет работать потому что будет использована Import Address Table
26K
17 октября 2010 года
3D-GRAF
41 / / 28.06.2008
Теперь всё понял :) Осталось только предусмотреть другие возможные варианты, знать бы только все возможные
8.2K
17 октября 2010 года
bagie2
299 / / 26.10.2008
написано уже, два по сути их варианта откуда брать имена функций. по умолчанию смотрим Import Name Table, а если он == 0 то берем из Import Address Table
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог