Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Вопросы про EXE и DLL (https://forum.antichat.xyz/showthread.php?t=101229)

criz 14.01.2009 22:03

Вопросы про EXE и DLL
 
Всем драсьте =)
Есть процесс, я получил список длл-ок, которые она использует. Как мне получить список функций, используемые процессом?
P.S. кто-нить качал сорцы отсюда?

KaZ@NoVa 14.01.2009 22:06

2 года прошло!!! Здохли? :(
Ты на дату посмотри!!!!... :(

criz 14.01.2009 22:13

Цитата:

2 года прошло!!! Здохли?
это шутко)))
Сабж?

cash$$$ 14.01.2009 22:36

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;


criz 14.01.2009 22:46

cash$$$, нет. Мне надо получить список функций, которые использует процесс

bons 14.01.2009 23:35

смотри в таблицу импорта exe-файла процесса.

criz 14.01.2009 23:39

Цитата:

Сообщение от bons
смотри в таблицу импорта exe-файла процесса.

Как? :)
P.S. нашел функцию ImageLoad()...

St0nX 14.01.2009 23:43

Есть плагин для Тотал командера им можно посмотреть таблицу импорта

Называется PEViewer

criz 15.01.2009 00:00

St0nX, замечательная вещь. Еще есть у Руссиновича ProccessExplorer и dumpbin(или как-то так) у VC++ :)
Только вот мне свое хочется.

bons 15.01.2009 00:31

в статье есть примеры по работе с таблицей импорта
http://wasm.ru/article.php?article=green2red02

criz 15.01.2009 01:34

Цитата:

в статье есть примеры по работе с таблицей импорта
http://wasm.ru/article.php?article=green2red02
спасиб, будем разбираться :)

criz 16.01.2009 21:14

Сделал вывод названий секций и их виртуальных адресов(VA). Результат:
Цитата:

Section: .text
VA: 360178
Section: .data
VA: 3601A0
Section: .bss
VA: 3601C8
Section: .idata
VA: 3601F0
Section: // пусто?
VA: 360218
Последняя секция без названия...это нормально? :)

FoX's 16.01.2009 22:21

Цитата:

Последняя секция без названия...это нормально?
в названиях может быть любой мусор. ОС их не проверяет :)

desTiny 16.01.2009 22:43

а) импорт - читай описание PE-формата
б) прога может быть упакована и восстановлять таблицу импорта в начале своей работы
в) прога может динамически подгружать функции - тогда у тебя немного шансов их найти, не реверся её

criz 16.01.2009 23:36

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;

тут вылетает экзепшн

criz 17.01.2009 00:21

ППЦ! Сделал :-) Вывыодится импорт :)
Осталось разобраться че я сделал)))
P.S. кому интересно, идите по ссылке , которую bons дал

criz 17.01.2009 17:30

Как определить тип файла(ехе или длл)?
Пробую вот так:
Код:

        if(hPE->FileHeader.Characteristics == IMAGE_FILE_EXECUTABLE_IMAGE)
                printf("File type: exe\n");


desTiny 17.01.2009 17:36

FileHeader->Characteristics->Dll

criz 17.01.2009 17:50

Цитата:

Сообщение от desTiny
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.

desTiny 17.01.2009 17:57

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

criz 17.01.2009 23:16

Вот, какое-то подобие dumpbin'у
Цитата:

http://slil.ru/26552715
:)
З.Ы. пока только работает с import table

dnd 18.01.2009 02:21

Есть книжка "Ассемблер и дизассемблирование" Пирогова, там в приложении еще одно подобие, но выводит импорт, экспорт, ресурсы и отладочную информацию, вобщем вот сурс - http://slil.ru/26553218 ;)

criz 22.02.2009 11:04

Товарищи, как прочитать таблицу импорта/экспорта запущенных процессов?

0x0c0de 22.02.2009 11:44

Цитата:

Сообщение от criz
Товарищи, как прочитать таблицу импорта/экспорта запущенных процессов?

1) вызываете функцию CreateToolhelp32Snapshot, затем Process32First, Process32Next (так же следует вызыввать Module32First/Next для получения списка модулей в процессе) пока не закончаться процессы
2)читаете из структуры PROCESSENTRY32 поле szExeFile. Маппите исп. модуль себе и работаете с импортом/экспортом. Второй вариант - можно так же прочесть поле MODULEENTRY32 modBaseAddr - получить базу загрузки модуля и modBaseSize - его размер. Скопировать себе с помощью ReadProcessMemory и п.3.

3) а далее работать с директорией экспорта/импорта. хорошо расписано тут

http://www.wasm.ru/article.php?article=green2red02#_Toc100906487

criz 22.02.2009 13:51

0x0c0de, спасиб. Вроде бы все так и делал.... только вот выдает ошибку доступа ("процесс уже занят") или как-то так... Будем искать ошибку.

criz 25.02.2009 20:05

Цитата:

Сообщение от 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: Не удается найти указанный файл.

0x0c0de 27.02.2009 15:38

Я хз как вы там писали

Код:

// 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\ или \??\ вначале добавляем \??\], но если вам надо разберетесь и доделаете

criz 28.02.2009 19:35

Цитата:

Сообщение от 0x0c0de
Я хз как вы там писали

Че-т херня какая-то... Как бы я не пытался открыть файл, получаю ошибку открытия файла :(

0x0c0de 28.02.2009 19:51

И сейчас проблемы? Мэппите потом, после того как хендл получили

xpsp2

http://s45.radikal.ru/i107/0902/bb/07d61e611a10.jpg

xpsp3
http://s40.radikal.ru/i090/0902/1c/cc3243bb41e3.jpg

vista

http://s48.radikal.ru/i121/0902/65/22d36c8ebcd8.jpg

win7

http://i034.radikal.ru/0902/f2/d6ae6efd1b1f.jpg



Я вообще-то тестирую код, перед тем как постить

criz 28.02.2009 20:16

Усе сделалось :) Проблема была в правах доступа к файлу.
Цитата:

Сообщение от 0x0c0de
Я вообще-то тестирую код, перед тем как постить

Я ж не сказал, что ваш код не рабочий :)
Мои глюки и мои ошибки :)

criz 28.02.2009 22:58

Есть файл trigraph.exe, Builder'овский. Так вот все PE-редакторы/вьюверы сообщают, что это не PE-файл. Проверьте плиз кто-нить этот файл, чем он отличается от других.
Цитата:

http://slil.ru/27008747
З.Ы. я у всех файлов проверяю IMAGE_DOS_SIGNATURE и IMAGE_NT_SIGNATURE.
З.З.Ы. файл чист, вот отчет:
Цитата:

http://www.virustotal.com/ru/analisis/775ac9fb279c878b8c6dc4e60b381a57

0x0c0de 28.02.2009 23:29

IMAGE_NT_SIGNATURE отсутствует )

criz 01.03.2009 00:39

Сделал проверку таким вот образом:
Код:

        if(PEh->Signature != IMAGE_NT_SIGNATURE)
                return;

получаю экзепшн...
З.Ы. магнитные бури что-ли сегодня...голова не пашет =\

0x0c0de 01.03.2009 08:04

поместите свой код в try-блок или проверяйте не выходит ли за границы выделенной под проекцию области памяти значение (смещение предположительного pe-заголовка+4+адрес начала проекции). Здесь как раз выход за границы имеет место быть (смотрела в файле trigraph.exe).

00005000 - выделено под проекцию

00010000 - смещение предполагаемого pe-заголовка

x0man 01.03.2009 10:34

Цитата:

Репутация: Специалист (1/104) ±

побороть это пока не удалось...
P.S. пытался через OpenFileMapping:
Сталобыть нахрен вообще репутация нужна... ппц... Специалисты.

criz 01.03.2009 12:18

0x0c0de, спасибо. Все работает :)
P.S. 2 x0man, я сюда не из-за плюсиков/звездочек пришел. Они мне вобще "параллельны" =)

x0man 01.03.2009 12:50

Вы смысла моих слов не понимаете. забейте.

criz 22.03.2009 15:57

Доброго времени суток! На rsdn есть статья, сделал все как там написано. Скомпилил 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;
}


0x0c0de 22.03.2009 16:50

Мне кажется или в этом коде нет функции 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). код, кстати у меня работает

criz 22.03.2009 17:40

Может дело в LoadLibrary? Я могу так из своей проги использовать эту длл?


Время: 21:25