Практические аспекты редактирования таблицы импорта

Тема в разделе "WASM.RESEARCH", создана пользователем ZloyPetrushkO, 3 апр 2011.

  1. ZloyPetrushkO

    ZloyPetrushkO New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    5
    Доброго времени суток!

    предистория такова:
    есть одна статическая длл-ка, а в ней в нужный момент выполнения кода мне нужно подменить значение регистра.регистр содержит координату, далее записывает ее в стек и отправляет в видеопамять. я собираюсь перед отправкой в видео память подставить свою координату и отправить ее в видео память.
    соотвествеено ето я планирую сделать путем передачи управления процедуре в собственно написанной длл-ке, которая рассчитает требуемую координату, далее вернет управление оригинальному коду и тот уже запишет в видеопамять нужную координату.место внедрения найдено,место для оператора call есть(за счет арифметических действий, которые уже не нужны, т.к. координата вычисляется в моей длл).поетому внедрение имеет смысл делать с затиранием ориг кода и вставлением туда операнда call.

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

    Задача весьма тривиальная, и по ней есть много литературы.Изучив соотвествующую литературу (Крис Касперски, статьи и туториалы по РЕ файлам и изменение в них и т.п. в т.ч. и с етого сайта) я нашел общую последовательность выполнения данной операции:
    необходимо написать патчер, который:
    1) отредактирует таблицу импорта оригинальной длл
    2) собственно подставит в нужное место оператор call
    3) ну собсна вот и все :)

    никаких защит и скрывнаия следов редактирования н етребуется. я канеш понимаю, что задача тривиальная...но вот....
    с теоритической частью все более менее понятно. а вот с практической-не совсем =/ сделать ето правильно(хотябы даже пока без патчера, а чисто ручками при помощи хекс редакторов не удается)
    впрочем, воспользовавшись поиском нашел темы, где товарищи писали что такой код можно наваять на плюсах чуть ли не за полчаса. но почему то никто исходничков так и не приложил...
    или я плохо искал.=/

    собственно я и прошу поетому помочь с практической частью:
    может есть у кого какие нибудь исходнички подобных патчеров для образца?
    правильно ли я понимаю, что исходя из структуры РЕ файла после таблицы импорта будет место забитое нулями для выравнивания размера секции?
    поделитесь плз практическим опытом кто как добавлял в длл вызов сторонней длл или ткните плз носом на статьи конкретно по теме написания подобных патчеров с примерами.

    Заранее спасибо!
    ЗЫ: если тема не в той ветке создана, прошу перенести в нужную ветку.
     
  2. GroundHog

    GroundHog New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2005
    Сообщения:
    35
    Если не хочется/не получается прописать руками, то
    для добавления своей dll в таблицу импорта рекомендую Stud PE:
    http://www.google.com/search?q=Stud+PE&ie=UTF-8
     
  3. ZloyPetrushkO

    ZloyPetrushkO New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    5
    большое спасибо!
    попробую обязательно :)
    ибо перед написание патчера мне нужно сделать хотябы как нибудь чтобы работало для того чтобы рзаобраться в процессе :)
     
  4. dr_godsl

    dr_godsl New Member

    Публикаций:
    0
    Регистрация:
    13 дек 2009
    Сообщения:
    60
    я делал так. расширял последнюю секцию на нужный размер с учетом выравнивания (IMAGE_OPTIONAL_HEADER.FileAlignment), переносил туда исправленную таблицу импорта... короче сорец вот, расписывать лень.
    Код (Text):
    1. RVAToOffset proc uses ebx hview:dword,rva:dword
    2.     mov ebx,hview
    3.     add ebx,(IMAGE_DOS_HEADER ptr [ebx]).e_lfanew
    4.     add ebx,sizeof dword
    5.     mov cx,(IMAGE_FILE_HEADER ptr [ebx]).NumberOfSections
    6.     movzx ecx,cx
    7.    
    8.     add ebx,sizeof IMAGE_FILE_HEADER + sizeof IMAGE_OPTIONAL_HEADER
    9.     mov edx,rva
    10. @@:
    11.     cmp edx,(IMAGE_SECTION_HEADER ptr [ebx]).VirtualAddress
    12.     jl @next_sec
    13.     mov eax,(IMAGE_SECTION_HEADER ptr [ebx]).VirtualAddress
    14.     add eax,(IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData
    15.     cmp edx,eax
    16.     jl @f
    17. @next_sec: 
    18.     add ebx,sizeof IMAGE_SECTION_HEADER
    19.     loop @b
    20.     xor eax,eax
    21.     ret
    22. @@:
    23.     mov eax,rva
    24.     sub eax,(IMAGE_SECTION_HEADER ptr [ebx]).VirtualAddress
    25.     add eax,(IMAGE_SECTION_HEADER ptr [ebx]).PointerToRawData
    26.     add eax,hview
    27.     ret
    28. RVAToOffset endp
    29.  
    30. AddImport proc szTarget:dword
    31. local strbuf:dword
    32. local hfile:dword
    33. local hmap:dword
    34. local hview:dword
    35. local tdw:dword
    36.  
    37. local ImportDir:dword
    38. local OrigImportOffs:dword
    39. local OrigImportSize:dword
    40. local SectionAlignment:dword
    41. local cblsRaw:dword
    42. local cblsVSize:dword
    43. local CheckSum:dword
    44.  
    45.     mov strbuf,func(HeapAlloc,pheap,HEAP_ZERO_MEMORY,100h)
    46.     invoke wsprintf,strbuf,chr$("%s.new_import"),szTarget
    47.     invoke CopyFile,szTarget,strbuf,FALSE
    48.     xor eax,eax
    49.     mov hfile,func(CreateFile,strbuf,GENERIC_ALL,eax,eax,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,eax)
    50.     cmp eax,INVALID_HANDLE_VALUE
    51.     jz @error
    52.     xor eax,eax
    53.     mov hmap,func(CreateFileMapping,hfile,eax,PAGE_READWRITE,eax,eax,eax)
    54.     test eax,eax
    55.     jz @error
    56.     xor eax,eax
    57.     mov hview,func(MapViewOfFile,hmap,FILE_MAP_READ or FILE_MAP_WRITE,eax,eax,eax)
    58.     test eax,eax
    59.     jz @error  
    60. ;получаем смещение и размер импорта  
    61.     mov ebx,hview
    62.     add ebx,(IMAGE_DOS_HEADER ptr [ebx]).e_lfanew
    63.     add ebx,sizeof IMAGE_FILE_HEADER + sizeof dword
    64.     lea ebx,(IMAGE_OPTIONAL_HEADER ptr [ebx]).DataDirectory ;считаем смещение import table
    65.     add ebx,sizeof IMAGE_DATA_DIRECTORY*1   ;Import
    66.    
    67.     mov ImportDir,ebx
    68.    
    69.     m2m OrigImportSize,dword ptr [ebx+4]
    70.     mov eax,[ebx]
    71.     test eax,eax
    72.     jz @error
    73.     mov OrigImportOffs,func(RVAToOffset,hview,eax)
    74. ;go to last section
    75.     mov ebx,hview
    76.     add ebx,(IMAGE_DOS_HEADER ptr [ebx]).e_lfanew
    77.     add ebx,sizeof dword
    78.    
    79.     mov eax,sizeof IMAGE_SECTION_HEADER
    80.     mul (IMAGE_FILE_HEADER ptr [ebx]).NumberOfSections
    81.     sub eax,sizeof IMAGE_SECTION_HEADER
    82.         push eax
    83.    
    84.     add ebx,sizeof IMAGE_FILE_HEADER
    85.  
    86. ;calc last section addition size's
    87.     mov ecx,OrigImportSize
    88.     add ecx,sizeof IMAGE_IMPORT_DESCRIPTOR + sizeof dword + sizeof dword + 20h
    89.     mov eax,(IMAGE_OPTIONAL_HEADER ptr [ebx]).FileAlignment
    90. @@:
    91.     cmp ecx,eax
    92.     jle @f
    93.     add eax,(IMAGE_OPTIONAL_HEADER ptr [ebx]).FileAlignment
    94.     jmp @b
    95. @@:
    96.     mov cblsRaw,eax
    97.    
    98.     mov ecx,(IMAGE_OPTIONAL_HEADER ptr [ebx]).SectionAlignment
    99. @@:
    100.     cmp ecx,eax
    101.     jle @f
    102.     add eax,(IMAGE_OPTIONAL_HEADER ptr [ebx]).FileAlignment
    103.     jmp @b
    104. @@:
    105.     mov cblsVSize,eax
    106.    
    107.     add ebx,sizeof IMAGE_OPTIONAL_HEADER
    108.         pop eax
    109.     add ebx,eax
    110.  
    111.     mov strbuf,func(HeapReAlloc,pheap,0,strbuf,cblsRaw)
    112.     mov ecx,cblsRaw
    113.     xor eax,eax
    114.     mov edi,strbuf
    115.     rep stosb
    116.  
    117.     mov ecx,(IMAGE_SECTION_HEADER ptr [ebx]).PointerToRawData
    118.     add ecx,(IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData
    119.     invoke SetFilePointer,hfile,ecx,0,FILE_BEGIN
    120.     invoke WriteFile,hfile,strbuf,cblsRaw,addr tdw,0
    121.    
    122.     mov edi,(IMAGE_SECTION_HEADER ptr [ebx]).PointerToRawData
    123.     add edi,(IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData
    124.     add edi,sizeof IMAGE_IMPORT_DESCRIPTOR
    125.     add edi,hview
    126.     mov esi,OrigImportOffs
    127.     mov ecx,OrigImportSize
    128.     rep movsb
    129.  
    130.     mov edi,(IMAGE_SECTION_HEADER ptr [ebx]).PointerToRawData
    131.     add edi,(IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData
    132.     add edi,hview
    133.     add edi,cblsRaw
    134.     sub edi,20h
    135.  
    136.     invoke lstrcat,edi,chr$("your.dll")
    137.     sub edi,8
    138.     mov dword ptr [edi],80000001h
    139.     mov eax,edi
    140.    
    141.     mov edi,(IMAGE_SECTION_HEADER ptr [ebx]).PointerToRawData
    142.     add edi,(IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData
    143.     add edi,hview
    144.  
    145.     sub eax,hview
    146.     sub eax,(IMAGE_SECTION_HEADER ptr [ebx]).PointerToRawData
    147.     add eax,(IMAGE_SECTION_HEADER ptr [ebx]).VirtualAddress
    148.     stosd           ;Import LookUp
    149.     xor eax,eax
    150.     stosd           ;Time/Date Stamp
    151.     stosd           ;Forward Chain
    152.     mov eax,(IMAGE_SECTION_HEADER ptr [ebx]).VirtualAddress
    153.     add eax,(IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData
    154.     add eax,cblsRaw
    155.     sub eax,20h
    156.     stosd           ;Name RVA
    157.     mov eax,OrigImportOffs
    158.     mov eax,dword ptr [eax+10h]
    159.     stosd           ;Addres Table RVA
    160.    
    161.     mov edi,ImportDir
    162.    
    163.     mov eax,(IMAGE_SECTION_HEADER ptr [ebx]).VirtualAddress
    164.     add eax,(IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData
    165.     stosd           ;rva таблицы
    166.     mov eax,OrigImportSize
    167.     add eax,sizeof IMAGE_IMPORT_DESCRIPTOR
    168.     stosd           ;размер таблицы
    169.     ;правим заголовок последней секции
    170.     ;SizeOfRawData
    171.     mov eax,cblsRaw
    172.     add (IMAGE_SECTION_HEADER ptr [ebx]).SizeOfRawData,eax
    173.     ;VirtualSize
    174.     mov eax,cblsVSize
    175.     add (IMAGE_SECTION_HEADER ptr [ebx]).Misc.VirtualSize,eax
    176.     ;Characteristics
    177.     mov (IMAGE_SECTION_HEADER ptr [ebx]).Characteristics,IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE or IMAGE_SCN_CNT_INITIALIZED_DATA
    178.  
    179.     add edi,18 *sizeof dword    ;Bound Import
    180.     xor eax,eax
    181.     stosd
    182.     stosd
    183.     ;IMAGE_OPTIONAL_HEADER.SizeOfImage
    184.     mov ebx,hview
    185.     add ebx,(IMAGE_DOS_HEADER ptr [ebx]).e_lfanew
    186.     add ebx,sizeof IMAGE_FILE_HEADER + sizeof dword
    187.     mov eax,(IMAGE_OPTIONAL_HEADER ptr [ebx]).SizeOfImage
    188.     add eax,cblsVSize
    189.     mov (IMAGE_OPTIONAL_HEADER ptr [ebx]).SizeOfImage,eax
    190.    
    191.     mov CheckSum,func(GetFileSize,hfile,0)
    192.     invoke LoadLibrary,chr$("imagehlp.dll")
    193.     test eax,eax
    194.     jz @f
    195.     invoke GetProcAddress,eax,chr$("CheckSumMappedFile")
    196.     test eax,eax
    197.     jz @f  
    198.  
    199.     mov edx,eax
    200.     invoke f4 ptr edx,hview,CheckSum,addr tdw,addr CheckSum
    201.     mov eax,CheckSum
    202.     mov (IMAGE_OPTIONAL_HEADER ptr [ebx]).CheckSum,eax
    203. @@:
    204.     invoke UnmapViewOfFile,hview
    205.     invoke CloseHandle,hmap
    206.     invoke CloseHandle,hfile
    207.     invoke HeapFree,pheap,0,strbuf
    208.     mov eax,TRUE
    209.     ret
    210. @error:
    211.     xor eax,eax
    212.     ret
    213. AddImport endp
     
  5. freyr

    freyr New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2010
    Сообщения:
    95
    detours от microsoft research, вроде умеет добавлять, если нужен код на СИ

    http://research.microsoft.com/en-us/projects/detours/
     
  6. ZloyPetrushkO

    ZloyPetrushkO New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    5
    спасибо всем за помощь!
    за примеры исходников отдельное большое спасибо!
    помогло, с таблицей импорта удачно разобрался. :)

    ----
    чтобы не создавать отдельную тему:
    сейчас остался один мелкий штришок в плане работы загрузчика. как известно-при загрузке длл загрузчик перебазирует длл в память. чаще всего-он ето делает в одно и то же место(в некое оптимальное смещение). используя таблицы экспорта/импорта и т.п. ессна при перебазировании он соотвествующим образом меняет код, чтобы ссылки указывали в нужное место. ессна можно прогрузиться под отладчиком, посмотреть куда он перебазирует и вычислить адрес и жестко забить его в код. программа будет рбаотать.

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

    собственно вот этот момент пока сделать не удается: вроде все делаю по образцу, но при загрузке загрузчик оставляет нужную строчку неизменной. т.е., как было.
    к примеру:загрузка перебазирует длл в 00001000. но мой оператор jmp ds:10101010(оп. код ff 25 10 10 10 10) при загрузке не изменяется, хотя по идее он должен загрузиться как jmp ds:10102010.
    поиски по мануалам и статьям о загрузчике пока эффекта не дали(
    может кто подскажет, по какому критерию загрузчик определяет какие адреса нада модифицировать при загрзке, а какие нет? ну или плз кинте ссылочкой на толковую статью(книгу) по работе загрзчика, где ето можно прочитать
    гуглом искал, чес слово.
    заранее спасибо! :)
     
  7. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Нифига не понятно что тебе надо.
    Ты про загрузку длл, в который ты хукаешь, в другое место? Если да то надо определять адрес ф-ции динамически, забивать жестко смещения это зло. В крайнем случае забивай RVA и потом корректируй на базу длл-ки.

    Твой жестко вбитый адрес никакой загрузчик не исправит. Есть релоки, но они для адресов внутри твоего модуля а не для внешних. Еще есть дельта смещение. Гугли :)
     
  8. dr_godsl

    dr_godsl New Member

    Публикаций:
    0
    Регистрация:
    13 дек 2009
    Сообщения:
    60
    не надо никаких джампов вписывать в код, твоего джампа не будет в релоках и загрузчик его пропустит. забей на это. загрузчик в любом случае выполнит точку входа в твою длл, отсюда и пляши. но не забывай, есть ограничения на то чего можно делать в точке входа, а чего нет.
     
  9. ZloyPetrushkO

    ZloyPetrushkO New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    5
    к сожалению у меня еще есть проблемы со знанием терминов(т.е. изъясняюсь на пальцах) и,похоже, с пониманием процесса работы загрузчика...
    да, вот именно что зло. но как сделать по доброму-над етим я сейчас как раз и работаю :)
    с наскоку взять ессна не получилось, поетому сейчас потихоньку изучаю теорию :)
    но она часто на английском, а ето еще больше вносит путаницу для меня в терминах(

    правильно ли я понимаю, что речь идет о корректировании точки rebasing while loading?
    т.е. смещения в памяти, начиная с которого прогружается и располагается в памяти машинный код длл-ки?

    ага) и ессна не исправляет он) и ето меня печалит)

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

    гм...а во всех найденных мной в гугле источниках и примерах все ето сводиться к примерно такому алгоритму:
    1) вычищаем свободное место(или делаем его путем добавления новой секции и т.д.)
    2) в ето место пишем код, суть которого сводиться к джампу на точку входа как на жесткий адрес(вот такой джамп нам нужен: FF 25 ХХ ХХ ХХ ХХ ХХ Jump to call gate, same privilege)
    3) в месте, где мы хотим врезаться, пишем относительный ближний call(relative near call),который ведет нас на джамп, который уже и передает управление др. длл...
    вот такой алгоритм я и реализовал...оно даже работает, но на жесткой адресации :)
    собственно тут я понял, что либо я чта не так понял в примерах, либо они чета не написали...начал копать...и копаю вот потихоньку по гуглу :)
    сейчас даже нашел пример исходника для простейшего виндоусовского загрузчика на плюсах :)

    спасибо всем откликнувшимся! :)
    с вашей помощь и помощью гугла я думаю все получиться :)
     
  10. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    хз, в который раз читаю что не могут найти документацию. Я в свое время прочитал какую-то доку по PE-формату на русском, и пару статей на васме, типа "об упаковщиках в последний раз", "от зеленого к красному" и т .д. Залазишь во все разделы и смотришь статьи и примеры.
     
  11. ZloyPetrushkO

    ZloyPetrushkO New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    5
    в моем случае вся проблема была в том, что я не знал точной терминологии, а общий смысл как раз представлял. в статьях то зачастую авторы допускают жаргонизмы, посему у меня и возникла путаница:гугл выдавал что то невнятное.

    Благодаря Вашим ключевым словам, что были указаны в постах выше общение с гуглом пошло намного живее и я нашел примерно следующее.

    утилита для редактирования релоков(релокаций,таблицы релокаций и т.п.) существует и называется
    Bin_RelocEditor_2008-7-23_21.12_RelocEdit (гугл ее находит легко на слово RelocEdit)
    например вот ссылочка: http://www.woodmann.com/collaborative/tools/index.php/RelocEditor

    гораздо интереснее обстоят дела с инструкцией к ней. она нашлась на одном форуме, где у меня антивирус ругался благим матом, посему сюда ее просто перепощу:
    вот собственно и все. дальше все банально :)
    ------------------------------------------------
    ЗЫ:алгоритм работает, все вроде хорошо. временин е было вс еотписаться,а ща вот решил таки запостить пост, ибо мало ли кому поможет при редактировании релоков. всем спасибо за помощь!
    тему имхо можно закрывать.