Просмотр полной версии : Вопросы про EXE и DLL
Всем драсьте =)
Есть процесс, я получил список длл-ок, которые она использует. Как мне получить список функций, используемые процессом?
P.S. кто-нить качал сорцы отсюда (http://forum.antichat.ru/thread28435.html)?
KaZ@NoVa
14.01.2009, 22:06
2 года прошло!!! Здохли? :(
Ты на дату посмотри!!!!... :(
2 года прошло!!! Здохли?
это шутко)))
Сабж?
criz
Для получения списка всех процессов в системе, если я не ошибаюсь можно получить так:
type
TPROCESS = packed record
ProcessId : dword;
ImageName : array [0..15] of Char;
pEPROCESS : dword;
ParrentPid: dword;
end;
PSYS_PROCESSES = ^TSYS_PROCESSES;
TSYS_PROCESSES = packed record
ProcessesCount: dword;
Process: array[0..0] of TPROCESS;
end;
{ Получение списка процессов прямым доступом к структурам ядра. }
function GetProcesses(): PSYS_PROCESSES;
var
Eprocess: array [0..$600] of byte;
CurrentStruct: dword;
CurrSize: dword;
OldPriority: dword;
begin
CurrSize := SizeOf(TSYS_PROCESSES);
GetMem(Result, CurrSize);
ZeroMemory(Result, CurrSize);
ZeroMemory(@Eprocess, $600);
CurrentStruct := UndocData.BaseProcStrAdr + UndocData.ActivePsListOffset;
OldPriority := GetThreadPriority($FFFFFFFE);
SetThreadPriority($FFFFFFFE, THREAD_PRIORITY_TIME_CRITICAL);
repeat
CurrentStruct := CurrentStruct - UndocData.ActivePsListOffset;
Ring0CopyMemory(pointer(CurrentStruct), @Eprocess, $220);
if pdword(dword(@Eprocess) + UndocData.ppIdOffset)^ > 0 then
begin
Inc(CurrSize, SizeOf(TPROCESS));
ReallocMem(Result, CurrSize);
Result^.Process[Result^.ProcessesCount].ProcessId :=
pdword(dword(@Eprocess) + UndocData.PidOffset)^;
Result^.Process[Result^.ProcessesCount].pEPROCESS := CurrentStruct;
lstrcpyn(@Result^.Process[Result^.ProcessesCount].ImageName,
PChar(dword(@Eprocess) + UndocData.NameOffset), 16);
Result^.Process[Result^.ProcessesCount].ParrentPid :=
pdword(dword(@Eprocess) + UndocData.ppIdOffset)^;
Inc(Result^.ProcessesCount);
end;
CurrentStruct := pdword(dword(@Eprocess) + UndocData.ActivePsListOffset)^;
if CurrentStruct < $80000000 then break;
until CurrentStruct = UndocData.BaseProcStrAdr + UndocData.ActivePsListOffset;
SetThreadPriority($FFFFFFFE, OldPriority);
end;
cash$$$, нет. Мне надо получить список функций, которые использует процесс
смотри в таблицу импорта exe-файла процесса.
смотри в таблицу импорта exe-файла процесса.
Как? :)
P.S. нашел функцию ImageLoad()...
Есть плагин для Тотал командера им можно посмотреть таблицу импорта
Называется PEViewer
St0nX, замечательная вещь. Еще есть у Руссиновича ProccessExplorer и dumpbin(или как-то так) у VC++ :)
Только вот мне свое хочется.
в статье есть примеры по работе с таблицей импорта
http://wasm.ru/article.php?article=green2red02
в статье есть примеры по работе с таблицей импорта
http://wasm.ru/article.php?article=green2red02
спасиб, будем разбираться :)
Сделал вывод названий секций и их виртуальных адресов(VA). Результат:
Section: .text
VA: 360178
Section: .data
VA: 3601A0
Section: .bss
VA: 3601C8
Section: .idata
VA: 3601F0
Section: // пусто?
VA: 360218
Последняя секция без названия...это нормально? :)
Последняя секция без названия...это нормально?
в названиях может быть любой мусор. ОС их не проверяет :)
а) импорт - читай описание PE-формата
б) прога может быть упакована и восстановлять таблицу импорта в начале своей работы
в) прога может динамически подгружать функции - тогда у тебя немного шансов их найти, не реверся её
2 desTiny:
а) читаю, мноооого чего читаю.
б) она не упакована, обычный "hello, world"
з.Ы. пытаюсь получить имя из IMAGE_IMPORT_DESCRIPTOR, пока ниче не выходит :(
PIMAGE_IMPORT_DESCRIPTOR Import;
PLOADED_IMAGE pli;
pli = ImageLoad("C:\\test.exe", NULL);
Import = (PIMAGE_IMPORT_DESCRIPTOR) pli->FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
тут вылетает экзепшн
ППЦ! Сделал :-) Вывыодится импорт :)
Осталось разобраться че я сделал)))
P.S. кому интересно, идите по ссылке (http://wasm.ru/article.php?article=green2red02) , которую bons дал
Как определить тип файла(ехе или длл)?
Пробую вот так:
if(hPE->FileHeader.Characteristics == IMAGE_FILE_EXECUTABLE_IMAGE)
printf("File type: exe\n");
FileHeader->Characteristics->Dll
FileHeader->Characteristics->Dll
Не, так низя :)
Есть такой способ:
if(PE->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)
printf("File type: EXE\n");
if(PE->FileHeader.Characteristics & IMAGE_FILE_DLL)
printf("File type: DLL\n");
В случае с ехе-файлом все норм, выводится File type: EXE,а если файл является dll'кой, то выводится и File type: EXE, и File type: DLL.
а я что сказал? я указал не объектное обращение к загруженному файлу на сях, а куда смотреть в пе-заголовке.
Вот, какое-то подобие dumpbin'у
http://slil.ru/26552715
:)
З.Ы. пока только работает с import table
Есть книжка "Ассемблер и дизассемблирование" Пирогова, там в приложении еще одно подобие, но выводит импорт, экспорт, ресурсы и отладочную информацию, вобщем вот сурс - http://slil.ru/26553218 ;)
Товарищи, как прочитать таблицу импорта/экспорта запущенных процессов?
Товарищи, как прочитать таблицу импорта/экспорта запущенных процессов?
1) вызываете функцию CreateToolhelp32Snapshot, затем Process32First, Process32Next (так же следует вызыввать Module32First/Next для получения списка модулей в процессе) пока не закончаться процессы
2)читаете из структуры PROCESSENTRY32 поле szExeFile. Маппите исп. модуль себе и работаете с импортом/экспортом. Второй вариант - можно так же прочесть поле MODULEENTRY32 modBaseAddr - получить базу загрузки модуля и modBaseSize - его размер. Скопировать себе с помощью ReadProcessMemory и п.3.
3) а далее работать с директорией экспорта/импорта. хорошо расписано тут
http://www.wasm.ru/article.php?article=green2red02#_Toc100906487
0x0c0de, спасиб. Вроде бы все так и делал.... только вот выдает ошибку доступа ("процесс уже занят") или как-то так... Будем искать ошибку.
1) вызываете функцию CreateToolhelp32Snapshot, затем Process32First, Process32Next (так же следует вызыввать Module32First/Next для получения списка модулей в процессе) пока не закончаться процессы
2)читаете из структуры PROCESSENTRY32 поле szExeFile. Маппите исп. модуль себе и работаете с импортом/экспортом.
Если в CreateFile передавать szExeFile, то получаю:
Error 32: Процесс не может получить доступ к файлу, так как этот файл занят друг
им процессом.
побороть это пока не удалось...
P.S. пытался через OpenFileMapping:
OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, "calc");
Error 2: Не удается найти указанный файл.
Я хз как вы там писали
// toolhelp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <Tlhelp32.h>
#include <ntdll.h>
#pragma comment (lib,"ntdll.lib");
VOID SetNeededPrivelege(VOID)
{
HANDLE hndl;
TOKEN_PRIVILEGES newpriv,prevpriv;
DWORD retl;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hndl))
{
if (LookupPrivilegeValue(0, L"SeDebugPrivilege", &newpriv.Privileges[0].Luid))
{
newpriv.PrivilegeCount = 1;
newpriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hndl, 0, &newpriv, sizeof(newpriv), &prevpriv, &retl);
}
CloseHandle(hndl);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hSnap,hFile,hMSnp;
PROCESSENTRY32 proc32;
MODULEENTRY32 moduleentry32;
NTSTATUS status;
OBJECT_ATTRIBUTES ObjAttr;
UNICODE_STRING usExeModName;
IO_STATUS_BLOCK ioStatus;
WCHAR wcPath[500];
SetNeededPrivelege();
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if( hSnap != INVALID_HANDLE_VALUE )
{
proc32.dwSize = sizeof(PROCESSENTRY32);
if( Process32First( hSnap, &proc32 ) )
{
do
{
hMSnp = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE,proc32.th32ProcessID);
if(hMSnp!=INVALID_HANDLE_VALUE)
{
moduleentry32.dwSize = sizeof( MODULEENTRY32 );
if(Module32First(hMSnp, &moduleentry32))
{
do{
if(lstrcmp(moduleentry32.szModule,proc32.szExeFile )==0)
{
memset(wcPath,0,500*2);
if(!((_wcsnicmp(moduleentry32.szExePath,
L"\\??\\",
lstrlen(L"\\??\\")) == 0)||
(_wcsnicmp(moduleentry32.szExePath,
L"\\SystemRoot\\",
lstrlen(L"\\SystemRoot\\")) == 0)
))
{
lstrcpy(wcPath,L"\\??\\");
lstrcat(wcPath,moduleentry32.szExePath);
}else
{
lstrcpy(wcPath,moduleentry32.szExePath);
}
RtlInitUnicodeString(&usExeModName,wcPath);
InitializeObjectAttributes(&ObjAttr,
&usExeModName,
OBJ_CASE_INSENSITIVE,
NULL, NULL);
status = NtCreateFile(&hFile,
FILE_READ_DATA,
&ObjAttr,
&ioStatus,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_WRITE|FILE_SHARE_READ,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE,
NULL,
0);
if (NT_SUCCESS(status))
{
wprintf(L"File %ws opened successfully\n",
wcPath);
wprintf(L" file size = %d bytes\n",GetFileSize(hFile,0));
NtClose(hFile);
}else
{
wprintf(L"Cannot open file %ws status = %X\n",
wcPath,
status);
}
}
}while( Module32Next(hMSnp, &moduleentry32));
}
}
}while(Process32Next(hSnap, &proc32));
}
}
Sleep(-1);
return 0;
}
Проверка конечно довольно ненадежная [если нет \SystemRoot\ или \??\ вначале добавляем \??\], но если вам надо разберетесь и доделаете
Я хз как вы там писали
Че-т херня какая-то... Как бы я не пытался открыть файл, получаю ошибку открытия файла :(
И сейчас проблемы? Мэппите потом, после того как хендл получили
xpsp2
http://s45.radikal.ru/i107/0902/bb/07d61e611a10.jpg (http://www.radikal.ru)
xpsp3
http://s40.radikal.ru/i090/0902/1c/cc3243bb41e3.jpg (http://www.radikal.ru)
vista
http://s48.radikal.ru/i121/0902/65/22d36c8ebcd8.jpg (http://www.radikal.ru)
win7
http://i034.radikal.ru/0902/f2/d6ae6efd1b1f.jpg (http://www.radikal.ru)
Я вообще-то тестирую код, перед тем как постить
Усе сделалось :) Проблема была в правах доступа к файлу.
Я вообще-то тестирую код, перед тем как постить
Я ж не сказал, что ваш код не рабочий :)
Мои глюки и мои ошибки :)
Есть файл trigraph.exe, Builder'овский. Так вот все PE-редакторы/вьюверы сообщают, что это не PE-файл. Проверьте плиз кто-нить этот файл, чем он отличается от других.
http://slil.ru/27008747
З.Ы. я у всех файлов проверяю IMAGE_DOS_SIGNATURE и IMAGE_NT_SIGNATURE.
З.З.Ы. файл чист, вот отчет:
http://www.virustotal.com/ru/analisis/775ac9fb279c878b8c6dc4e60b381a57
IMAGE_NT_SIGNATURE отсутствует )
Сделал проверку таким вот образом:
if(PEh->Signature != IMAGE_NT_SIGNATURE)
return;
получаю экзепшн...
З.Ы. магнитные бури что-ли сегодня...голова не пашет =\
поместите свой код в try-блок или проверяйте не выходит ли за границы выделенной под проекцию области памяти значение (смещение предположительного pe-заголовка+4+адрес начала проекции). Здесь как раз выход за границы имеет место быть (смотрела в файле trigraph.exe).
00005000 - выделено под проекцию
00010000 - смещение предполагаемого pe-заголовка
Репутация: Специалист (1/104) ±
побороть это пока не удалось...
P.S. пытался через OpenFileMapping:
Сталобыть нахрен вообще репутация нужна... ппц... Специалисты.
0x0c0de, спасибо. Все работает :)
P.S. 2 x0man, я сюда не из-за плюсиков/звездочек пришел. Они мне вобще "параллельны" =)
Вы смысла моих слов не понимаете. забейте.
Доброго времени суток! На rsdn есть статья (http://www.rsdn.ru/article/baseserv/IntercetionAPI.xml), сделал все как там написано. Скомпилил dll-ку "перехватчик", затем написал прогу:
#include <windows.h>
int main(int argc, char* argv[])
{
LoadLibrary("C:\\test.dll");
MessageBox(NULL, "Test", "test", MB_OK);
return 0;
}
Вылетает экзепшн. Подскажите плиз где ошибка?
P.S. вот исходник дллки:
// dll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <windows.h>
#include "dll.h"
void IntFunc(void);
BOOL WINAPI NewMessage(HWND hwnd, char *text, char *hdr, UINT utype);
#pragma pack(push, 1)
struct jmp_far
{
BYTE instr_push;
DWORD arg;
BYTE instr_ret;
};
#pragma pack(pop)
BYTE old[6];
DWORD adr_MessageBoxA;
DWORD written;
jmp_far jump;
BOOL WINAPI Intercept_MessageBoxA(HWND hwnd, char *text, char *hdr, UINT utype)
{
//Сначала восстанавливаем 6 первых байт функции. Это не обязательное
// действие, просто мы решили подшутить над пользователем, и все
// сообщения функции MessageBoxA переделать на свои, поэтому нам придется
// вызвать оригинальную функцию, а для этого следует восстановить ее адрес:
WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA,
(void*)&old, 6, &written);
//Здесь вы можете порезвиться от души и выполнить любые, пришедшие вам
// в голову действия. Мы просто заменили сообщение функции на свое:
char *str = "Hi From MessageBOX!!!!";
//Вызываем оригинальную функцию через указатель
((BOOL (__stdcall*)(HWND, char*, char*, UINT))adr_MessageBoxA)(hwnd,
str, hdr, utype);
//Снова заменяем 6 байт функции на команду перехода на нашу функцию
WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA,
(void*)&jump, 6,&written);
return TRUE;
}
void InterceptFunctions(void)
{
DWORD op;
//сначала получим абсолютный адрес функции для перехвата
adr_MessageBoxA = (DWORD)GetProcAddress(GetModuleHandle("user32.dll"),
"MessageBoxA");
if(adr_MessageBoxA == 0)
{
MessageBox(NULL, "Can`t get adr_MessageBoxA", "Error!", 0);
return;
}
// Зададим машинный код инструкции перехода, который затем впишем
// в начало полученного адреса:
jump.instr_push = 0x68;
jump.arg = (DWORD)&Intercept_MessageBoxA;
jump.instr_ret = 0xC3;
//Прочитаем и сохраним первые оригинальные 6 байт стандартной API функции
ReadProcessMemory(GetCurrentProcess(),(void*) adr_MessageBoxA,
(void*)&old, 6, &written);
//Запишем команду перехода на нашу функцию поверх этих 6-ти байт
WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA,
(void*)&jump, sizeof(jmp_far), &written);
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH )
{
InterceptFunctions();
}
return TRUE;
}
Мне кажется или в этом коде нет функции VirtualProtectEx ?
--added
Кстати вот была тема
http://forum.antichat.ru/thread32176.html
А, сейчас посмотрела код WriteProcessMemory
7C80222C 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
7C80222F 8D45 14 LEA EAX,DWORD PTR SS:[EBP+14]
7C802232 50 PUSH EAX
7C802233 6A 40 PUSH 40
7C802235 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
7C802238 50 PUSH EAX
7C802239 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
7C80223C 50 PUSH EAX
7C80223D 57 PUSH EDI
7C80223E 895D FC MOV DWORD PTR SS:[EBP-4],EBX
7C802241 FFD6 CALL ESI ; ntdll.ZwProtectVirtualMemory
VirtualProtect не нужен сталобыть, PAGE_EXECUTE_READWRITE уже есть (0x40). код, кстати у меня работает
Может дело в LoadLibrary? Я могу так из своей проги использовать эту длл?
>>Может дело в LoadLibrary? Я могу так из своей проги использовать эту длл?
Да, можете, не в этом дело. У меня отработало норм, я же говорю
Just-in-time debugger заюзайте (OllyDbg например удобно). И скажите в каком месте эксепшн
Не знаю что изменилось, но все заработало. Я лишь перекомпилировал длл-ку %)
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot