Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {$apptype console}
- program RelDump; uses windows, imagehlp;
- function HexStr(val:integer):string;
- var i:integer; ch:byte;
- begin Result := '';
- for i:=7 downto 0 do begin ch := val shr (i*4) and $f or $30;
- if ch > $39 then inc (ch,7); Result := Result + char(ch)
- end;
- end;
- type
- //
- TReloc_Table = packed record
- { Relocations Table - полублоки, патч-смещений, длиной до $FFF }
- { |------------- SIZE --------------| |------------- SIZE --------------| }
- { DWORD VA, DWORD SIZE, WORD,WORD,WORD DWORD VA, DWORD SIZE, WORD,WORD,WORD }
- VA:cardinal; Size:cardinal;OFFSETS: array[1..1000] of word;
- end;
- type
- TSections=array[0..10] of TImageSectionHeader;
- // конвертор 'виртуального' адреса в 'реальный' (смещение файла)
- function VA_TO_RAW (VA:integer;PE:PImageNtHeaders):integer;
- var
- Sections: ^TSections; i:byte; label done1,done2;
- begin
- //установить указатель на структуры ImageSectionHeader (.code/.data/etc) }
- Sections:= pointer(integer(@PE.OptionalHeader.Magic) +
- PE.FileHeader.SizeOfOptionalHeader);
- // перебор секций до совпадения или попадания значения в диапазон секции
- for i:=0 to PE.FileHeader.NumberOfSections-1 do
- if VA = Sections[i].VirtualAddress then goto done1 else
- if VA < Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize
- then goto done2; Result := 0; // writeln ('OOOPS!!!');
- exit; // хм...ничего не найдено
- done1: Result := Sections[i].PointerToRawData; exit;
- done2: Result := VA - Sections[i].VirtualAddress +
- Sections[i].PointerToRawData; exit;
- end; // ps: код древний,ужасный.. но что странно рабочий
- var
- i: integer; img: PLoadedImage;
- PE:PImageNtHeaders; str: string;
- RelocTab : ^TReloc_Table;
- data :^integer; position: integer;
- begin
- str:= ParamStr(1); if str = '' then str := 'FLEngine.dll';
- img:= ImageLoad(pchar(str), nil);
- if img = nil then exit;
- MapAndLoad(pchar(str), nil, img, true, false);
- PE := img.FileHeader;
- // находим смещение файла на таблицу релоков
- RelocTab := pointer(
- VA_to_RAW (img.FileHeader.OptionalHeader.DataDirectory
- [IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, PE)
- // нормализуем его до загруженого в память
- + integer(img.MappedAddress)
- );
- (* // альтернативный вариант
- for i := 0 to img.NumberOfSections-1 do
- begin
- Section:= pointer(integer(img.Sections)+SizeOf(TImageSectionHeader)*i);
- str:= pchar(@Section.Name);
- RelocTab := pointer(integer(img.MappedAddress)+Section.PointerToRawData);
- if str = '.reloc'then break;
- end; *)
- repeat //сканим таблицу релоков
- Position := VA_TO_RAW (RelocTab.VA, PE) + (integer(PE) - $100);
- // входим в смещения
- for i := 1 to ((RelocTab.Size -8) div 2) do
- begin if RelocTab.Offsets[i] = 0 then break; // 0 - конец секции
- // todo: желательно ввести проверку типа релока
- data := pointer (position+ (RelocTab.Offsets[i] and not $F000));
- // печатаем...
- writeln (
- HexStr($100+integer(data)-integer(PE)) ,' ',
- HexStr($100+integer(@RelocTab.Offsets[i])-integer(PE)) , ' ',
- HexStr( data^ )
- );
- end; // Конец перебора смещений
- //Смотрим следующий блок
- RelocTab := pointer(cardinal(RelocTab)+ RelocTab.Size);
- until RelocTab.VA = 0; { конец таблицы VA=0 }
- ImageUnload (img);
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement