![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как считать версию файла,образ которого находится в памяти ?
Vorobyev Sergey © (2003-07-02 14:19:00)
Привет всем!
ВОПРОС: Можно ли как-нибудь определить версию файла (аналогично функции API GetFileVersionInfo) для образа файла, который находится в памяти, НЕ ЗАПИСЫВАЯ ЕГО НА ДИСК (даже во временную папку)..?
ПОЯСНЕНИЕ: Дело в том, что исполнимый файл, версию которого необходимо определить, находится в ресурсах другой программы. Файл извлекается в память, необходимо определить его версию и в зависимости от этого он записывается на диск (или нет) и исполняется..
--
Спасибо
Vorobyev Sergey (2003-07-03 08:49:00) [21]
> AlexRush
Пытаюсь разобраться.. Честно говоря для меня это немного сложно, но пытаюсь..
Если бегло, то это возможно как раз то, что мне нужно..
Попробовал в Delphi6, вот так с ходу не откомпилилось..
Описания для PIMAGE_DOS_HEADER и т.п. взял из "Delphi\Demos\ResXplor\rxtypes.pas"
Пока такие вопросы:
1. Что за функция mkptr?
2. Какие юниты еще надо подключать?
AlexRush (2003-07-02 19:37:00) [22]Тестировал так:
ResourceExtractToFile(MapPEfromResource("#101","DIGITHEX"),
"#101","DIGITHEX",PathName);
Чуть не забыл :)
//function MapPEfromResource(resName,resType:string):DWORD;
// ПОЛУЧАЕТ Имя и Тип ресурса,который содержит PE-файл.
// ( выделяет сама!)
Тестировал так:
ResourceExtractToFile(MapPEfromResource("#101","DIGITHEX"),
"#101","DIGITHEX",PathName);
Чуть не забыл :)
//function MapPEfromResource(resName,resType:string):DWORD;
// ПОЛУЧАЕТ Имя и Тип ресурса,который содержит PE-файл.
// Грузит PE - в память (выделяет сама!) согласно с таблицей секций
// ВОЗВРАЩАЕТ хендл модуля, который можно использовать
// в функциях работы С РЕСУРСАМИ.
AlexRush (2003-07-02 19:34:00) [23]Аж самому интересно стало.
Написал процедурку. Работает, проверял.
function MapPEfromResource(resName,resType:string):DWORD;
var hFile,hRes,hResData:DWORD;
ptrResLock :pointer;
ptrMZ :PIMAGE_DOS_HEADER;
ptrPE :PIMAGE_NT_HEADERS;
ptrSH :PIMAGE_SECTION_HEADER;
hMappedPE :PIMAGE_DOS_HEADER;
dw :DWORD;
i :integer;
p:pointer;
begin
result:=0;
// Ищем ресурс, содержащий ПЕ
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;// внутренний код ошибки
exit;
end;
// Загружаем оный
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
// получаем указатель на его данные
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);
// для наглядности ptrMZ - указатель на DOS заголовок
ptrMZ:=ptrResLock;
// ptrPE - указатель на PE заголовок
ptrPE:=mkptr(ptrMZ,ptrMZ^._lfanew);
// проверка сигнатуры ПЕ
if ptrPE^.Signature<>IMAGE_NT_SIGNATURE
then exit;
// ptrSH - указатель на таблицу секций
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));
// здесь считаем необходимый размер памяти под загрузку ПЕ
dw:=0;
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
if (ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData)>dw
then dw:=ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData;
inc(ptrSH);
end;
inc(dw,sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+4096);
// и выделяем ее
hMappedPE:=HeapAlloc(GetProcessHeap(),0,dw);
// копируем DOS заголовок, Stub и PE заголовок
dw:=sizeof(ptrMZ^)+ptrMZ^._lfanew+sizeof(ptrPE^);
CopyMemory(hMappedPE,
ptrMZ,
dw);
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));
// копируем таблицк секций
CopyMemory(mkptr(hMappedPE,dw),
ptrSH,
ptrPE^.FileHeader.NumberOfSections*sizeof(ptrSH^));
// копируем секции согласно RVA
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
p:=mkptr(hMappedPE,ptrSH^.VirtualAddress);
CopyMemory(p,
mkptr(ptrMZ,ptrSH^.PointerToRawData),
ptrSH^.SizeOfRawData);
inc(ptrSH);
end;
// ВНИМАНИЕ !!!
// НЕ призводится развязка relocations"сов,
// Запускать (передавать управление нельзя !)
// рэзалт - хендл (он же указатель) загруженного модуля
result:=DWORD(hMappedPE);
end;
Ресурс в файл:
function ResourceExtractToFile(hInst:DWORD;resName,resType,FullFileName:string):DWORD;stdcall;
var hFile,dw_writed:DWORD;
hRes,hResData:DWORD;
ptrResLock:pointer;
begin
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;
exit;
end;
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);
if not Assigned(ptrResLock)
then begin
result:=3;
exit;
end;
//ptrResLock
hFile:= CreateFile("_testFile.exe",
GENERIC_WRITE,
FILE_SHARE_WRITE or FILE_SHARE_READ,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile=INVALID_HANDLE_VALUE)
then begin
result:=4;
exit;
end;
dw_writed:=SizeofResource(hInstance,hRes);
if not LongBool(WriteFile(hFile,ptrResLock,dw_writed,@dw_writed,nil))
then begin
CloseHandle(hFile);
result:=5;
exit;
( hFile)
Аж самому интересно стало.
Написал процедурку. Работает, проверял.
function MapPEfromResource(resName,resType:string):DWORD;
var hFile,hRes,hResData:DWORD;
ptrResLock :pointer;
ptrMZ :PIMAGE_DOS_HEADER;
ptrPE :PIMAGE_NT_HEADERS;
ptrSH :PIMAGE_SECTION_HEADER;
hMappedPE :PIMAGE_DOS_HEADER;
dw :DWORD;
i :integer;
p:pointer;
begin
result:=0;
// Ищем ресурс, содержащий ПЕ
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;// внутренний код ошибки
exit;
end;
// Загружаем оный
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
// получаем указатель на его данные
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);
// для наглядности ptrMZ - указатель на DOS заголовок
ptrMZ:=ptrResLock;
// ptrPE - указатель на PE заголовок
ptrPE:=mkptr(ptrMZ,ptrMZ^._lfanew);
// проверка сигнатуры ПЕ
if ptrPE^.Signature<>IMAGE_NT_SIGNATURE
then exit;
// ptrSH - указатель на таблицу секций
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));
// здесь считаем необходимый размер памяти под загрузку ПЕ
dw:=0;
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
if (ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData)>dw
then dw:=ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData;
inc(ptrSH);
end;
inc(dw,sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+4096);
// и выделяем ее
hMappedPE:=HeapAlloc(GetProcessHeap(),0,dw);
// копируем DOS заголовок, Stub и PE заголовок
dw:=sizeof(ptrMZ^)+ptrMZ^._lfanew+sizeof(ptrPE^);
CopyMemory(hMappedPE,
ptrMZ,
dw);
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));
// копируем таблицк секций
CopyMemory(mkptr(hMappedPE,dw),
ptrSH,
ptrPE^.FileHeader.NumberOfSections*sizeof(ptrSH^));
// копируем секции согласно RVA
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
p:=mkptr(hMappedPE,ptrSH^.VirtualAddress);
CopyMemory(p,
mkptr(ptrMZ,ptrSH^.PointerToRawData),
ptrSH^.SizeOfRawData);
inc(ptrSH);
end;
// ВНИМАНИЕ !!!
// НЕ призводится развязка relocations"сов,
// Запускать (передавать управление нельзя !)
// рэзалт - хендл (он же указатель) загруженного модуля
result:=DWORD(hMappedPE);
end;
Ресурс в файл:
function ResourceExtractToFile(hInst:DWORD;resName,resType,FullFileName:string):DWORD;stdcall;
var hFile,dw_writed:DWORD;
hRes,hResData:DWORD;
ptrResLock:pointer;
begin
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;
exit;
end;
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);
if not Assigned(ptrResLock)
then begin
result:=3;
exit;
end;
//ptrResLock
hFile:= CreateFile("_testFile.exe",
GENERIC_WRITE,
FILE_SHARE_WRITE or FILE_SHARE_READ,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile=INVALID_HANDLE_VALUE)
then begin
result:=4;
exit;
end;
dw_writed:=SizeofResource(hInstance,hRes);
if not LongBool(WriteFile(hFile,ptrResLock,dw_writed,@dw_writed,nil))
then begin
CloseHandle(hFile);
result:=5;
exit;
end;
CloseHandle(hFile);
result:=0;
end;
Игорь Шевченко (2003-07-02 17:26:00) [24]
Можно. Чтением и обработкой ресурса типа RT_VERSION
Soft (2003-07-02 16:15:00) [25]
The CreateFileMapping function creates a named or unnamed file-mapping object for the specified file.
HANDLE CreateFileMapping(
HANDLE hFile, // handle to file to map
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // optional security attributes
DWORD flProtect, // protection for mapping object
DWORD dwMaximumSizeHigh, // high-order 32 bits of object size
DWORD dwMaximumSizeLow, // low-order 32 bits of object size
LPCTSTR lpName // name of file-mapping object
);