Посл.ответ |
Сообщение |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 25 июня 2006 00:05 · Личное сообщение · #1
С помощью чего в Delphi можно работать с PE файлами?
Неужели всё надо через BlockRead..BlockWrite?
| Сообщение посчитали полезным: |
|
 Ранг: 353.0 (мудрец) Активность: 0.37↘0 Статус: Участник resreveR
|
Создано: 25 июня 2006 00:09 · Личное сообщение · #2
есть и стандартные структуры для работы с пе-файлами(поищи в хелпах,юнитах)
есть модули, которые написали хорошие люди ;)
f5a5_25.06.2006_CRACKLAB.rU.tgz - PE_Files.pas
----- Тут не могла быть ваша реклама | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 25 июня 2006 00:11 · Личное сообщение · #3
Что за стандартные юниты?
| Сообщение посчитали полезным: |
Ранг: 23.8 (новичок) Активность: 0.02↘0 Статус: Участник
|
Создано: 25 июня 2006 01:14 · Личное сообщение · #4
sniperZ пишет:
Что за стандартные юниты?
В которых описан формат PE, lord_Phoenix дал те PE_Files.pas, там помоему класс pe_file, в нем все есть.
| Сообщение посчитали полезным: |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 25 июня 2006 01:27 · Поправил: Hellspawn · Личное сообщение · #5
а зачем? в самой дельфи всё уже описано давно)
маппируй файл и в путь
var
...
dos : PImageDosHeader;
nt : PImageNtHeaders;
...
begin
dos:=PImageDosHeader(dword(MEMPTR));
nt:=PImageNtHeaders(Pointer(Dword(dos)+Dword(dos._lfanew)));
end;
----- [nice coder and reverser] | Сообщение посчитали полезным: |
 Ранг: 353.0 (мудрец) Активность: 0.37↘0 Статус: Участник resreveR
|
Создано: 25 июня 2006 01:30 · Личное сообщение · #6
Hellspawn пишет:
а зачем? в самой дельфи всё уже описано давно)
я про это и говорил ;)
а модуль Др.Головы поудобней думаю будет,кому как, да и доп. функции типа ребилда кому нужны %)
----- Тут не могла быть ваша реклама | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 25 июня 2006 14:16 · Личное сообщение · #7
Хорошо
Var dos : PImageDosHeader;
Чтобы мне прочитать dos.e_magic мне надо
BlockRead(f,dos.e_magic,2)?
| Сообщение посчитали полезным: |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 25 июня 2006 14:21 · Поправил: Hellspawn · Личное сообщение · #8
да зачем же так жестоко? открой файл сначала...
var
...
dos : PImageDosHeader;
MEMPTR:Pointer;
PE,MEMSZ:Dword;
с:word;
...
PE:=CreateFile(PChar(F_PEFilePath),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
MEMSZ:=GetFileSize(PE,nil);
MEMPTR:=MapViewOfFile(FM,FILE_MAP_WRITE, 0, 0, MEMSZ);
...
dos:=PImageDosHeader(dword(MEMPTR));
теперь можешь обращаться к любому полю стр-ры, например
c:=dos.e_magic;
----- [nice coder and reverser] | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 28 июня 2006 10:41 · Личное сообщение · #9
TImageSectionHeader.Name: packed array[0..IMAGE_SIZEOF_SHORT_NAME-1] of Byte;
Как преобразовать Name в строку(название секции)?
| Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 28 июня 2006 11:42 · Личное сообщение · #10
Что, никто не может помочь!!?
| Сообщение посчитали полезным: |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 28 июня 2006 12:18 · Личное сообщение · #11
блин, ну ты ППЦ! читай доки, это же элементарно!
посмотри на время своих постов! прошёл всего 1 час и ты хочешь, чтобы кто-то ответил...
например можно так:
var
s1 : array [0..7] of char;
begin
MOVE(sect.name,s1,8);
end;
----- [nice coder and reverser] | Сообщение посчитали полезным: |
 Ранг: 793.4 (! !), 568thx Активность: 0.74↘0 Статус: Участник Шаман
|
Создано: 28 июня 2006 12:24 · Личное сообщение · #12
PChar(@sl)
----- Yann Tiersen best and do not fuck | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 28 июня 2006 19:25 · Поправил: sniperZ · Личное сообщение · #13
В чём тогда ошибка?
procedure TForm1.Button2Click(Sender: TObject);
Var i: byte;
n: byte;
s: PChar;
f: file;
dos: TImageDosHeader;
nt: TImageNTHeaders;
O_H: TImageOptionalHeader;
F_H: TImageFileHeader;
S_H: array[1..16] of TImageSectionHeader;
begin
Memo.Clear;
AssignFile(f,e.Text);
Reset(f,1);
BlockRead(f,dos,sizeof(dos));
Seek(f,dos._lfanew);
BlockRead(f,nt,SizeOf(nt));
BlockRead(f,S_H,SizeOf(S_H));
Seek(f,nt.OptionalHeader.SizeOfHeaders);
s:='';
for i:=0 to (nt.FileHeader.NumberOfSections-1) do
begin
BlockRead(f,S_H[i],SizeOf(S_H[i]));
s:=PChar(@S_H[i].Name);
Memo.Lines.Add(string(s));
s:='';
end;
CloseFile(f);
end;
По идеи в Memo должен появиться список секций, а появляется какая то чепуха иногда с названиями секций.
| Сообщение посчитали полезным: |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 28 июня 2006 19:51 · Личное сообщение · #14
чтобы получить первую секцию - надо сдвинуться на смещение:
Dword(NT)+SizeOf(TImageNtHeaders)
и всё будет пахать...
----- [nice coder and reverser] | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 28 июня 2006 22:52 · Личное сообщение · #15
Hellspawn пишет:
чтобы получить первую секцию - надо сдвинуться на смещение:
Dword(NT)+SizeOf(TImageNtHeaders)
и всё будет пахать...
Так компилятор выдаёт ошибку,а вот...
Seek(f,dos._lfanew+SizeOf(TImageNtHeaders));
...получается!!!
Всё равно спасибо,т.к. ты единственный кто мне помогает.
| Сообщение посчитали полезным: |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 28 июня 2006 23:09 · Личное сообщение · #16
странно не должно ошибки быть...
а почему ты через указатели не работаешь? там же всё намного
проще, удобнее и быстрее  и если не секрет, что же ты пишешь?
----- [nice coder and reverser] | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 29 июня 2006 00:24 · Личное сообщение · #17 |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 29 июня 2006 11:29 · Личное сообщение · #18
нет, просто работа с самим файлом через указатели, я выше пример приводил!
----- [nice coder and reverser] | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 29 июня 2006 17:44 · Личное сообщение · #19 |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 30 июня 2006 11:38 · Поправил: sniperZ · Личное сообщение · #20
Iczelion пишет:
Это главная схема по нахождению важной структуры данных в PE-файле:
От DOS-заголовка вы переходите к PE-заголовку
Получаете адрес директории данных в опциональном заголовке.
Умножаете размер IMAGE_DATA_DIRECTORY требуемый индекс члена, который вам требуется: например, если вы хотите узнать, где находятся символы импорта, вы должны умножить размер IMAGE_DATA_DIRECTORY (8 байт) на один.
Добавляете результат к адресу директории данных, и теперь у вас есть адрес структуры IMAGE_DATA_DIRECTORY, которая содержит информацию о желаемой структуре данных.
Что за адрес директории данных?
Пробовал так...
Seek(f,SizeOf(_IMAGE_DATA_DIRECTORY)+nt.OptionalHeader.DataDirectory[1 ].VirtualAddress);..
...не работает.
Iczelion пишет:
IMAGE_IMPORT_BY_NAME STRUCT
Hint dw ?
Name1 db ?
IMAGE_IMPORT_BY_NAME ENDS
Как мне этот тип перевести в тип Delphi?
| Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 30 июня 2006 12:46 · Личное сообщение · #21
Правильно я отвечаю на свой последний вопрос?
P_IMAGE_IMPORT_BY_NAME=^TIMAGE_IMPORT_BY_NAME;
TIMAGE_IMPORT_BY_NAME=packed record
Hint: word;
Name: byte;
end;
| Сообщение посчитали полезным: |
Ранг: 35.1 (посетитель), 1thx Активность: 0.01↘0 Статус: Участник
|
Создано: 30 июня 2006 12:51 · Личное сообщение · #22
Выход на таблицу импорта(отложенного импортаб экспорта) можно сделать примерно таким кодом:
////////////////////////////////////////////////////////////////////// //////////
//
// ********************************************************************** ******
// * Project : PEDump
// * Unit Name : DebugHlp.pas
// * Purpose : Работа с ImageHlpAPI и реализация функций
// отсутствующих в Windows 98/ME
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2006 г.
// * Version : 1.00
// ********************************************************************** ******
//
unit DebugHlp;
interface
uses
Windows;
{$I import.inc}
function MapAndLoad(ImageName, DllPath: LPSTR; LoadedImage: PLoadedImage;
DotDll, ReadOnly: Bool): Bool; stdcall; external 'Imagehlp.dll';
function UnMapAndLoad(LoadedImage: PLoadedImage): Bool; stdcall;
external 'Imagehlp.dll';
function ImageRvaToVa(NtHeaders: PImageNtHeaders; Base: Pointer;
Rva: ULONG; var LastRvaSection: PImageSectionHeader): Pointer;
function ImageDirectoryEntryToData(Base: Pointer; MappedAsImage: ByteBool;
DirectoryEntry: Word; var Size: ULONG): Pointer;
implementation
function FieldOffset(const Struc; const Field): Cardinal;
begin
Result := Cardinal(@Field) - Cardinal(@Struc);
end;
function IMAGE_FIRST_SECTION(NtHeader: PImageNtHeaders): PImageSectionHeader;
begin
Result := PImageSectionHeader(Cardinal(NtHeader) +
FieldOffset(NtHeader^, NtHeader^.OptionalHeader) +
NtHeader^.FileHeader.SizeOfOptionalHeader);
end;
function ImageRvaToSection(NtHeaders: PImageNtHeaders; Base: Pointer;
Rva: ULONG): PImageSectionHeader;
var
NtSection: PImageSectionHeader;
I: Integer;
begin
Result := nil;
NtSection := IMAGE_FIRST_SECTION(NtHeaders);
for I := 0 to NtHeaders^.FileHeader.NumberOfSections - 1 do
if (Rva >= NtSection.VirtualAddress) and
(Rva < NtSection.VirtualAddress + NtSection.SizeOfRawData) then
begin
Result := NtSection;
Exit;
end
else
Inc(NtSection);
end;
function ImageRvaToVa(NtHeaders: PImageNtHeaders; Base: Pointer;
Rva: ULONG; var LastRvaSection: PImageSectionHeader): Pointer;
var
NtSection: PImageSectionHeader;
begin
Result := nil;
NtSection := LastRvaSection;
if (LastRvaSection = nil) or (Rva < NtSection^.VirtualAddress) or
(Rva < NtSection^.VirtualAddress + NtSection^.SizeOfRawData) then
NtSection := ImageRvaToSection(NtHeaders, Base, Rva);
if NtSection = nil then Exit;
if LastRvaSection <> nil then
LastRvaSection := NtSection;
Result := Pointer(DWORD(Base) + (Rva - NtSection^.VirtualAddress) +
NtSection^.PointerToRawData);
end;
// Усеченная версия ImageDirectoryEntryToData
// Не реализованы варианты при следующих значениях:
// OptionalHeader->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC
// OptionalHeader->Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC
function ImageDirectoryEntryToData(Base: Pointer; MappedAsImage: ByteBool;
DirectoryEntry: Word; var Size: ULONG): Pointer;
const
IMAGE_NT_OPTIONAL_HDR32_MAGIC = $10B;
IMAGE_NT_OPTIONAL_HDR64_MAGIC = $20B;
IMAGE_ROM_OPTIONAL_HDR_MAGIC = $107;
var
DOSHeader: PImageDosHeader;
NTHeader: PImageNtHeaders;
FileHeader: TImageFileHeader;
NtSection: PImageSectionHeader;
OptionalHeader: TImageOptionalHeader;
DirectoryAddress: DWORD;
I: Integer;
begin
Result := nil;
if (DWORD(Base) and 1) = 1 then
Base := Pointer((DWORD(Base) and not 1));
DOSHeader := PImageDosHeader(Base);
if IsBadReadPtr(Pointer(Base), SizeOf(TImageNtHeaders)) then Exit;
if (DOSHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then Exit;
NTHeader := PImageNtHeaders(DWORD(DOSHeader) + DWORD(DOSHeader^._lfanew));
if NTHeader^.Signature <> IMAGE_NT_SIGNATURE then Exit;
FileHeader := NTHeader^.FileHeader;
if FileHeader.Machine <> IMAGE_FILE_MACHINE_I386 then Exit;
OptionalHeader := NTHeader^.OptionalHeader;
if OptionalHeader.Magic <> IMAGE_NT_OPTIONAL_HDR32_MAGIC then Exit;
if DirectoryEntry >= OptionalHeader.NumberOfRvaAndSizes then
begin
Size := 0;
Exit;
end;
DirectoryAddress :=
OptionalHeader.DataDirectory[DirectoryEntry].VirtualAddress;
if DirectoryAddress = 0 then
begin
Size := 0;
Exit;
end;
Size := OptionalHeader.DataDirectory[DirectoryEntry].Size;
if MappedAsImage and (DirectoryAddress < OptionalHeader.SizeOfHeaders) then
begin
Result := Pointer(DWORD(Base) + DirectoryAddress);
Exit;
end;
NtSection := ImageRvaToSection(NTHeader, Base, DirectoryAddress);
if NtSection = nil then
begin
Size := 0;
Exit;
end;
for I := 0 to FileHeader.NumberOfSections - 1 do
if (DirectoryAddress >= NtSection^.VirtualAddress) and
(DirectoryAddress < NtSection^.VirtualAddress + NtSection^.SizeOfRawData) then
begin
Result := Pointer(DWORD(Base) +
(DirectoryAddress - NtSection^.VirtualAddress) + NtSection^.PointerToRawData);
Break;
end
else
Inc(NtSection);
end;
end.
Содержимое: import.inc
const
IMAGE_ORDINAL_FLAG = DWORD($80000000);
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11;
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13;
type
PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;
{$EXTERNALSYM PIMAGE_IMPORT_BY_NAME}
_IMAGE_IMPORT_BY_NAME = record
Hint: Word;
Name: array [0..0] of Char;
end;
{$EXTERNALSYM _IMAGE_IMPORT_BY_NAME}
IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME;
{$EXTERNALSYM IMAGE_IMPORT_BY_NAME}
TImageImportByName = IMAGE_IMPORT_BY_NAME;
PImageImportByName = PIMAGE_IMPORT_BY_NAME;
PIMAGE_THUNK_DATA32 = ^IMAGE_THUNK_DATA32;
{$EXTERNALSYM PIMAGE_THUNK_DATA32}
_IMAGE_THUNK_DATA32 = record
case Integer of
0: (ForwarderString: PBYTE);
1: (Function_: PDWORD);
2: (Ordinal: DWORD);
3: (AddressOfData: PIMAGE_IMPORT_BY_NAME);
end;
{$EXTERNALSYM _IMAGE_THUNK_DATA32}
IMAGE_THUNK_DATA32 = _IMAGE_THUNK_DATA32;
{$EXTERNALSYM IMAGE_THUNK_DATA32}
TImageThunkData32 = IMAGE_THUNK_DATA32;
PImageThunkData32 = PIMAGE_THUNK_DATA32;
TIIDUnion = record
case Integer of
0: (Characteristics: DWORD);
1: (OriginalFirstThunk: PIMAGE_THUNK_DATA32);
end;
PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
{$EXTERNALSYM PIMAGE_IMPORT_DESCRIPTOR}
_IMAGE_IMPORT_DESCRIPTOR = record
Union: TIIDUnion;
TimeDateStamp: DWORD; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
ForwarderChain: DWORD; // -1 if no forwarders
Name: DWORD;
FirstThunk: PIMAGE_THUNK_DATA32; // RVA to IAT (if bound this IAT has actual addresses)
end;
{$EXTERNALSYM _IMAGE_IMPORT_DESCRIPTOR}
IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
{$EXTERNALSYM IMAGE_IMPORT_DESCRIPTOR}
TImageImportDescriptor = IMAGE_IMPORT_DESCRIPTOR;
PImageImportDescriptor = PIMAGE_IMPORT_DESCRIPTOR;
{$EXTERNALSYM ImgDelayDescr}
ImgDelayDescr = packed record
grAttrs: DWORD; // attributes
szName: DWORD; // pointer to dll name
phmod: PDWORD; // address of module handle
{ TODO : probably wrong declaration }
pIAT: TImageThunkData32; // address of the IAT
{ TODO : probably wrong declaration }
pINT: TImageThunkData32; // address of the INT
{ TODO : probably wrong declaration }
pBoundIAT: TImageThunkData32; // address of the optional bound IAT
{ TODO : probably wrong declaration }
pUnloadIAT: TImageThunkData32; // address of optional copy of original IAT
dwTimeStamp: DWORD; // 0 if not bound,
// O.W. date/time stamp of DLL bound to (Old BIND)
end;
TImgDelayDescr = ImgDelayDescr;
PImgDelayDescr = ^ImgDelayDescr;
PloadedImage = ^TLoadedImage;
{$EXTERNALSYM _LOADED_IMAGE}
_LOADED_IMAGE = record
ModuleName: LPSTR;
hFile: THandle;
MappedAddress: PChar;
FileHeader: PImageNtHeaders;
LastRvaSection: PImageSectionHeader;
NumberOfSections: ULONG;
Sections: PImageSectionHeader;
Characteristics: ULONG;
fSystemImage: ByteBool;
fDOSImage: ByteBool;
Links: TListEntry;
SizeOfImage: ULONG;
end;
{$EXTERNALSYM LOADED_IMAGE}
LOADED_IMAGE = _LOADED_IMAGE;
LoadedImage = _LOADED_IMAGE;
TLoadedImage = _Loaded_IMAGE;
Пример использования:
if MapAndLoad(PChar(PEFile), nil, @liImageInfo, True, True) then
begin
try
// Получаем указатель на таблицу экспорта
pExportDirectory := ImageDirectoryEntryToData(liImageInfo.MappedAddress,
False, IMAGE_DIRECTORY_ENTRY_EXPORT, nDirSize);
if (pExportDirectory <> nil) then
begin
| Сообщение посчитали полезным: |
Ранг: 35.1 (посетитель), 1thx Активность: 0.01↘0 Статус: Участник
|
Создано: 30 июня 2006 12:57 · Личное сообщение · #23
Если хочешь могу дать целиком проект, только сыроват он немного, нет времени все подчистить.
| Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 30 июня 2006 13:35 · Поправил: sniperZ · Личное сообщение · #24
Iczelion пишет:
Это главная схема по нахождению важной структуры данных в PE-файле:
От DOS-заголовка вы переходите к PE-заголовку
Получаете адрес директории данных в опциональном заголовке.
Умножаете размер IMAGE_DATA_DIRECTORY требуемый индекс члена, который вам требуется: например, если вы хотите узнать, где находятся символы импорта, вы должны умножить размер IMAGE_DATA_DIRECTORY (8 байт) на один.
Добавляете результат к адресу директории данных, и теперь у вас есть адрес структуры IMAGE_DATA_DIRECTORY, которая содержит информацию о желаемой структуре данных.
Пробовал так...
Seek(f,SizeOf(_IMAGE_DATA_DIRECTORY)+nt.OptionalHeader.DataDirectory[1 ].VirtualAddress);..
...не работает.
Что за адрес директории данных?
Вы мне лучше на этот вопрос ответьте!
Я хочу сам разобратся со всем.
| Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 30 июня 2006 13:37 · Личное сообщение · #25
Hellspawn, жду отвоего ответа!
| Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 30 июня 2006 14:04 · Личное сообщение · #26
Ассемблерщики, переведите мне этот код на Delphi (приблизительно,хоть схему)
RVAToOffset PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD
mov esi,pFileMap
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
mov edi,RVA ; edi == RVA
mov edx,esi
add edx,sizeof IMAGE_NT_HEADERS
mov cx,[esi].FileHeader.NumberOfSections
movzx ecx,cx
assume edx:ptr IMAGE_SECTION_HEADER
.while ecx>0 ; check all sections
.if edi>=[edx].VirtualAddress
mov eax,[edx].VirtualAddress
add eax,[edx].SizeOfRawData
.if edi < eax ; The address is in this section
mov eax,[edx].VirtualAddress
sub edi,eax
mov eax,[edx].PointerToRawData
add eax,edi ; eax == file offset
ret
.endif
.endif
add edx,sizeof IMAGE_SECTION_HEADER
dec ecx
.endw
assume edx:nothing
assume esi:nothing
mov eax,edi
ret
RVAToOffset endp
| Сообщение посчитали полезным: |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 30 июня 2006 14:08 · Поправил: Hellspawn · Личное сообщение · #27
а зачем переводить то? обычная функция RVA To Offset
Function RvaToFileOffset(rva:dword):dword;
var
i:integer;
z:dword;
begin
Result:=0;
for i:=0 to Sectionlist.count-1 do
begin
Section:=PSection(SectionList[i]);
if ((RVA>=Section.rva) and (RVA<=Section.rva+Section.physical_size)) then
begin
z:=Section.physical_offs+RVA-Section.rva;
If (Section.physical_offs<nt.OptionalHeader.FileAlignment)
and (nt.OptionalHeader.FileAlignment=$200) then z:=RVA-Section.rva;
Result:=z;
exit;
end;
If ((Rva < Section.rva) and (i=0)) then
begin
z:=Rva;
Result:=z;
exit;
end;
end;
end;
----- [nice coder and reverser] | Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 01 июля 2006 13:15 · Личное сообщение · #28
Hellspawn, объясни пожалуйта принцип алгаритма.
Или дай ссылку на док.
| Сообщение посчитали полезным: |
 Ранг: 990.2 (! ! !), 380thx Активность: 0.68↘0 Статус: Модератор Author of DiE
|
Создано: 01 июля 2006 23:03 · Поправил: Hellspawn · Личное сообщение · #29
берём RVA для перевода, перебираем все секции по очереди,
если RVA принадлежит секции то переводим в оффсет
два примечания, проверка на выравнивание файла и смещение первой секции (винупак, нспак)
и ещё Section.rva+Section.physical_size - по идеи здесь нужно плюсовать не физический размер. а виртуальный, но на некоторых пакерах получаются не правильные зн-ия поэтому делаем так
(кстати LordPE DLX делает также).
----- [nice coder and reverser] | Сообщение посчитали полезным: |
Ранг: 450.1 (мудрец) Активность: 0.26↘0 Статус: Участник
|
Создано: 01 июля 2006 23:27 · Личное сообщение · #30
sniperZ
скачай исходники PEOptimizer by Dr.Golova там все это будет, в лучшем виде
www.uinc.ru/scripts/load.cgi?files/dr.golova/PE_Optimizer.zip
| Сообщение посчитали полезным: |