Форум программистов, компьютерный форум, киберфорум
Van111
Войти
Регистрация
Восстановить пароль
Рейтинг: 4.00. Голосов: 1.

отлов API функций ЧУЖОГО процесса

Запись от Van111 размещена 02.06.2012 в 13:12

наконец то я сделал это, больше всего мне помогла 22 глава книге Рихтеа, а всё остальное это БРЕД или извращения
комментарии к коду я приводить почти не буду
опишу функции

inject_dll.cpp
HANDLE GetProcessHandle(LPSTR szExeName)
функция получения хэндла(уже открытого хэндла) по имени процесса, функция элементарна и её разных вариантов на разных языках куча в Инете

unsigned long WINAPI call_inject_dll(LPVOID lpParameter);
функция созданного потока в чужом процессе ,всё что она делает ,это обращается по адресу 0x7c801d7b(это функция LoadLibraryA находящаяся в ядре kernel32,её адрес для всех процессов одинаковый)

dll_catch.cpp (dll библиотека)
void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
функция которую я позаимствовал у Рихтера ,даже названия не изменил).заменяет текущий адрес функции на адрес функции перехватчика


void GetCurrentProcessName(ULONG ID ,LPSTR szExeName);
почти тоже самое что и GetProcessHandle, только записывает в строку szExeName, имя процесса ,находит его по ID(ведь наша dll находится в чужом процессе, следственно GetCurrentProcessId получит его ID )

void INIT ();
эту функцию я собрал по кусочкам из статьи Рихтера ,она отсылает функции void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
которая принимает: dll в которой описана подменяемая функция , адрес подменяемой функции, адрес функции перехватчика, базу текущего процесса


int WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
функция перехватчик ,тут нечего сказать, вызовет MessageBox(0,"1","2",0) и вернёт управление

вот коды программ
inject_dll.cpp - можно win32 вариант ,можно консольный
inject_dll.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//---------------------------------------------------------------------------
#include "windows.h"
#include "Imagehlp.h"
#include "Tlhelp32.h"
#include "string.h"
#include <iostream>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
#define MAXMODULE 250
using namespace std;
 
 
 
typedef void (WINAPI* MYPROC)(...);
HANDLE GetProcessHandle(LPSTR szExeName);
unsigned long WINAPI call_inject_dll(LPVOID lpParameter);
 
 
 
 
 
 
int main(int argc, char* argv[])
{
        char s[100];
        HANDLE hProc;
        ULONG dwSize;
        char mod[MAXMODULE]="c:\\dll_catch";
 
        hProc =GetProcessHandle("test.exe");
        LPVOID lpDATA = VirtualAllocEx(hProc, NULL, 4048 , MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        LPVOID lpCODE = VirtualAllocEx(hProc, NULL, 4048 , MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        WriteProcessMemory( hProc, lpDATA, mod, strlen(mod), &dwSize);
        WriteProcessMemory( hProc, lpCODE, call_inject_dll, 2024, &dwSize);
        CreateRemoteThread(hProc,0,0,(LPTHREAD_START_ROUTINE)lpCODE,lpDATA,0,0);
 
        system("Pause");
        return  0;
}
 
HANDLE GetProcessHandle(LPSTR szExeName)
{
        PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
        if(Process32First(hSnapshot, &Pc))
        {
                do
                {
                if(!strcmp(Pc.szExeFile, szExeName))
                        {
                        return OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pc.th32ProcessID);
                        }
                }
                while(Process32Next(hSnapshot, &Pc));
        }
        return NULL;
}
 
unsigned long WINAPI call_inject_dll(LPVOID lpParameter)
{
 
MYPROC fLoadLibraryA;
(void*)fLoadLibraryA =(void*)0x7c801d7b ;
fLoadLibraryA(lpParameter);
 
for(;;){}
}

вот код dll
dll_catch.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "windows.h"
#include "Tlhelp32.h"
#include "Imagehlp.h"
#include "iostream.h"
#include "fstream.h"
void GetCurrentProcessName(ULONG ID ,LPSTR szExeName);
void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);
void INIT ();
int WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch( fdwReason ){
        case DLL_PROCESS_ATTACH:
                        INIT();
            break;
        case DLL_THREAD_ATTACH:
 
            break;
        case DLL_THREAD_DETACH:
 
            break;
        case DLL_PROCESS_DETACH:
 
            break;    
    }
    return TRUE;  
}
 
void INIT ()
{
       char s[50];
       PROC MessageBOX = GetProcAddress(GetModuleHandle("User32"), "MessageBoxA");
       GetCurrentProcessName(GetCurrentProcessId(),s);
       HMODULE hmodCaller = GetModuleHandle(s);
       PROC m;
       (void*)m=MyMessageBox;
       ReplaceIATEntryInOneMod("USER32.DLL", MessageBOX,m,hmodCaller);
       return;
}
 
void GetCurrentProcessName(ULONG ID ,LPSTR szExeName)
{
        PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
        if(Process32First(hSnapshot, &Pc))
        {
                do
                {
                        if(Pc.th32ProcessID==ID)
                        {
                                strcpy(szExeName,Pc.szExeFile);
                                return ;
                        }
                }
                while(Process32Next(hSnapshot, &Pc));
        }
}
 
 
 
void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
{
        ULONG ulSize;
        ULONG tmp=0;
        PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(hmodCaller, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
        if (pImportDesc == NULL)
                return;
        for (; pImportDesc->Name; pImportDesc++)
        {
                PSTR pszModName =  (PSTR)((PBYTE) hmodCaller + pImportDesc->Name);
                if (lstrcmpiA(pszModName, pszCalleeModName) == 0)
                        break;
        }
        if (pImportDesc->Name == 0)
                return;
        PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ((PBYTE) hmodCaller + pImportDesc->FirstThunk);
        for (; pThunk->u1.Function; pThunk++)
        {
 
                PROC* ppfn = (PROC*) &pThunk->u1.Function;
                BOOL fFound = (*ppfn == pfnCurrent);
                if (fFound)
                {
                        VirtualProtect(hmodCaller,0x16000,PAGE_READWRITE,&tmp);
                        WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, 4, 0 );
                        VirtualProtect(hmodCaller,0x16000,tmp,&tmp);
                        return;
                }
        }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
        MessageBox(0,"1","2",0);
        return 0;
}


и на последок если хотите отлавливать и вновь загружаемые функции вам надо поставить отслежку двух импортируемых функций
алгоритм
1:LoadLibrary
тут мы должны сравнить имя dll , если наша то
вызвать системную LoadLibrary
и запомнить её хэндл
иначе
вызвать системную LoadLibrary
2:GetProcessAddress
сравниваем полученный хэндл с сохранённым , и имя функции с именем функции которую мы хотим перехватить, если всё совпало, то
вернуть подменную функцию ,иначе вернуть нормальный адрес функции
не забывайте что при сравнении строк что функции MessageBox и LoadLibrary нет, есть функции MessageBoxA и LoadLibraryA
Всего комментариев 15
Комментарии
  1. Старый комментарий
    Как написано у Рихтера, для надёжного использования метода перехвата с использованием подмены адреса в секции импорта, надо перехватывать не только LoadLibraryA и GetProcessAddress, но и LoadLibraryW, LoadLibraryExA, LoadLibraryExW. По этой причине (того, что нам придётся перехватывать 5 функций дополнительно, причём в каждом модуле) и придумываются всякий "БРЕД и извращения". И если требуется перехватить 1-2 функции, а в дополнение к ним ставить обработчики перехвата ещё 5 функций не хочется, то можно, вполне, воспользоваться и методом, против которого он предупреждает - заменой первых 5 байт в теле перехватываемой функции. А чтобы избежать неприятных последствий, о которых он предупреждает, связанных с возможностью вызова не до конца подменённой функции, следует использовать инструкции mov из набора SSE, способные атомарно писать 8 байтов.
    А вообще, если требуется защитить свою программу от перехвата функций по описанному Рихтером методу, достаточно написать свою функцию GetProcessAddress, что совсем не сложно, и получать адреса функций при помощи неё. Ну а для защиты по методу подмены первых байт функции, надо прочитать первые байты функции в образе на диске и сравнить их с таковыми в адресном пространстве процесса. Необходимость в подобном может возникнуть, например, если вы пишете менеджер исполняемых процессов с защитой от подмены списка процессов троянскими программами на уровне пользователя. Так как ряд троянских программ для сокрытия себя в системе использует перехват функций удаляя свои данные из списка процессов, ключей автозапуска реестра, списка файлов. Правда, подобные методы сейчас легко палятся антивирусами, и некоторые авторы троянов сознательно отказываются от их использования, но тем не менее, прячущихся подобным образом тоже хватает, благо данные методы и рабочие примеры широко известны и доступны.
    Запись от Subrealist размещена 02.06.2012 в 19:23 Subrealist вне форума
  2. Старый комментарий
    А вообще, если требуется защитить свою программу от перехвата функций по описанному Рихтером методу, достаточно написать свою функцию GetProcessAddress, что совсем не сложно, и получать адреса функций при помощи неё
    а ещё проще обратится к её адресу в kernel32, а можно просто использовать путеводитель по написанию вирусов - там написано как искать dll функцию по базе библиотеки

    заменой первых 5 байт в теле перехватываемой функции
    полюбому придётся инжектировать код вызывающий dll, иначе это подходит только для текущего процесса

    И если требуется перехватить 1-2 функции, а в дополнение к ним ставить обработчики перехвата ещё 5 функций не хочется, то можно, вполне, воспользоваться и методом, против которого он предупреждает - заменой первых 5 байт в теле перехватываемой функции
    ну и что это даст , жертва по прежнему сможет вызвать несколько нам известных из пяти функций и получить новый указатель на отлавливаемую

    а если надо просто шпионить за dll файлом то легче просто подменить dll и по мере надобнасти вызывать функции которые просит прога из реальной dl а не пустышки перехватчика, а перехватчик будет только записывать отладочную информацию
    Запись от Van111 размещена 02.06.2012 в 19:51 Van111 вне форума
  3. Старый комментарий
    Цитата:
    а ещё проще обратится к её адресу в kernel32, а можно просто использовать путеводитель по написанию вирусов - там написано как искать dll функцию по базе библиотеки
    Это не проще. Это одно и тоже. Разве что здесь не идёт речь об оформлении кода в отдельную функцию.
    Цитата:
    полюбому придётся инжектировать код вызывающий dll, иначе это подходит только для текущего процесса
    Не обязательно. ReadProcessMemory/WriteProcessMemory - позволяет читать/писать код в адресное пространство любого процесса, доступного пользователю для записи. dll нам в этом случае больше нужна для того, чтобы обрабатывать перехват функций, так как этот код должен выполнятся в адресном пространстве вызывающего процесса. Но и эта проблема решаема. Ничто не мешает нам найти в адресном пространстве другого процесса места, куда мы можем записать свой код. Гранулярность выделения памяти равна 4 Кб и после загрузки любой из dll остаётся свободное место, куда мы можем записать свой код. Другое дело, что факт записи в адресное пространство другого процесса вызывает подозрения у антивирусов.
    Но про 5 байтов vs подмена импорта я написал не относительно использования - неиспользования dll, а к тому, что у бредовых и извращённый методов тоже могут быть свои преимущества.
    Цитата:
    ну и что это даст , жертва по прежнему сможет вызвать несколько нам известных из пяти функций и получить новый указатель на отлавливаемую
    Не сможет, так как мы подменили начало кода самой функции в dll. Сделали это так, что теперь, когда она начинает исполнятся, первой выполняемой ей инструкцией является безусловный переход на наш код. Для большинства функций, первые две инструкции, это формирование стекового кадра. Мы это можем сделать за неё, выполнить требуемые нам действия, а затем, не восстанавливая стековый кадр, передать управление изначальной функции на точку после джампа.
    В том то и преимущество записи этих пяти байт, что мы, единожды их записав, будем отлавливать все вызовы функции, пусть они идут хоть из впоследствии загружаемых dll, хоть получаются через GetProcAddress, хоть через самостоятельно написанный её аналог.
    Цитата:
    а если надо просто шпионить за dll файлом то легче просто подменить dll и по мере надобнасти вызывать функции которые просит прога из реальной dl а не пустышки перехватчика, а перехватчик будет только записывать отладочную информацию
    Можно и так, но тогда нам понадобится написать переходник для каждой функции, вызываемой в подменяемой dll всеми модулями программы. Потом решим мы перехватывать функции в другой программе, и нам придётся дорабатывать и нашу подменяющую dll. И для каждой длл писать свою подменяющую, с переходниками для кучи функций, которые мы не будем использовать. А используя технику подмены 5 байт мы легко, просто и быстро устанавливаем перехват требуемой нами функции, непосредственно в месте её вызова, остальные функции при этом не трогаем. Загружаемых программой модулей также не касаемся.
    Я вовсе не пытаюсь доказать, будто подмена 5 байт, то бишь сплайсинг, это просто круто, а то, что написано у Рихтера - отстой. Я лишь пишу о том, что у разных методов есть свои преимущества и недостатки, и не стоит с ходу называть их бредом и извращениями.
    Запись от Subrealist размещена 02.06.2012 в 21:53 Subrealist вне форума
  4. Старый комментарий
    ну да ты прав(спасибо за комментарии).ну далеко не каждому программисту под силу запись 5 байт).
    плюс нам понадобится в подменной функции вызывать LoadLobrary и GetProcessAdress для загрузки прикладных функций. Плюс включение проверки загружены ли функции или нет. Кстати незнаешь сколько свободного места в dll файле?
    Запись от Van111 размещена 02.06.2012 в 22:39 Van111 вне форума
  5. Старый комментарий
    Цитата:
    ну далеко не каждому программисту под силу запись 5 байт).
    Ну я понимаю, можно программировать в визуальных средах или 1С, получать за это неплохие деньги и на этом основании считать себя крутым программером. Но, если человек занимается системным программированием, то как он может мирится с неумением записать 5 байт или незнанием основ ассемблера я не понимаю.
    Цитата:
    плюс нам понадобится в подменной функции вызывать LoadLobrary и GetProcessAdress для загрузки прикладных функций. Плюс включение проверки загружены ли функции или нет.
    Не понял, в каких случаях нам придётся делать это?
    Цитата:
    Кстати незнаешь сколько свободного места в dll файле?
    Исполняемые файлы, а также файлы dll, sys под виндоус имеют PE-формат. Их представление, когда они лежат на диске, и когда они проецированы в память исполняемой программы несколько отличается.
    http://education.kulichki.net/comp/hack/27.htm
    http://msdn.microsoft.com/en-u... 63119.aspx
    Файл состоит из секций. Узнать, сколько секций, что это за секции можно, например, воспользовавшись утилитой PE Tools, открыть его там и нажать кнопку Sections.
    Файл загружается по секциям. Свободное место есть после каждой секции. Но секция секции рознь. По второй ссылке есть описание характеристик секций. Если секция запрещена для записи, то можно посчитать остающееся свободным место как VirtualSize-RawSize. При этом нам надо смотреть и другие характеристики секций, в соответствие с нашими требованиями, и если надо, то при помощи VirtualProtectEx изменить аттрибуты нужных страниц секции.
    Размещение своего кода в конце секций модулей - это один из примеров размещения своего кода в другом процессе. Для этих же целей можно воспользовавшись VirtualAllocEx выделить себе память в другом процессе.
    Запись от Subrealist размещена 03.06.2012 в 12:22 Subrealist вне форума
  6. Старый комментарий
    Subrealist, спасибо большое за информацию.

    Ну я понимаю, можно программировать в визуальных средах или 1С, получать за это неплохие деньги и на этом основании считать себя крутым программером. Но, если человек занимается системным программированием, то как он может мирится с неумением записать 5 байт или незнанием основ ассемблера я не понимаю.
    ты прав, но просто хотелось чтобы кодеры с++ ,тоже смогли отлавливать функции чужого процесса

    Не понял, в каких случаях нам придётся делать это?
    ну например функция сравнения строк ,измерение её длины, например мне очень нравятся с++ объектно ориентированные функции ввода -вывода которые смогут создать красивый(свободно просматриваемый блокнотом) дебуг файл и т д и т п .

    Исполняемые файлы, а также файлы dll, sys под виндоус имеют PE-формат. Их представление, когда они лежат на диске, и когда они проецированы в память исполняемой программы несколько отличается.
    ну да, помню когда в текстовеке смотришь на заголовок он весит 400h байт, а в память все 1000h.

    кстати а не проще создать свою секцию в конце секций и записать туда код отладчика?

    и ещё насчёт полной подмены dll можно написать прогу которая будет работать с таблицей экспорта и в результате выдавать готовый с++ код
    например так:
    dword WINAPI function1(...) // или не WINAPI , зависит от dll
    {
    MYPROC proc=(void*)GetProcessAddress(HH,"function1");
    proc();
    return; //насчёт return не уверен возможно вместо этого оператора будет стоять мой asm код который бы не обнулил eax!
    }
    ....
    при формирование dll можно все пустышки скинуть в файл dump.h , всмысле мусор
    а, функции которые надо отлавливать - засунуть в файл debug.h
    HH -это идентификатор реальной dll , его мы получим в dllmain ProcessAtach
    а ,если моя dllmain ещё и таблицу импорта оригинала накроет будет вообще круто

    кто знает может скоро в блоге появится статья о том что я выше написал)
    Запись от Van111 размещена 03.06.2012 в 13:46 Van111 вне форума
  7. Старый комментарий
    [QUOTE]кстати а не проще создать свою секцию в конце секций и записать туда код отладчика?[QUOTE]
    Тут вопрос, скорее, не в том, проще или нет, а когда лучше поступить именно так, а когда по другому.
    http://www.wasm.ru/article.php?article=pemodify
    [QUOTE]и ещё насчёт полной подмены dll можно написать прогу которая будет работать с таблицей экспорта и в результате выдавать готовый с++ код[QUOTE]
    Точно так же можно написать и программу, которая будет устанавливать для другой программы перехват требуемого числа функций в требуемых dll используя метод замены 5 байт, и передачу управления с них на функции в одной единственной нашей dll. Подобным образом работают API-шпионы. Можно взять и какой-нибудь уже готовый, если у нас нет каких-либо особых требований к тому, как должен обрабатываться перехват. И без всякого использования подменяемых dll. Если руководствоваться бритвой Оккама, то не стоит умножать сущности без необходимости. Однако, если есть необходимость использовать именно подмену dll, то тогда, другое дело.
    Цитата:
    ну например функция сравнения строк
    Опять не понял, каким образом это относится к перехвату функций методом подмены первых байт в её теле.
    Запись от Subrealist размещена 03.06.2012 в 15:39 Subrealist вне форума
  8. Старый комментарий
    Опять не понял, каким образом это относится к перехвату функций методом подмены первых байт в её теле.
    ну я имел в виду, то что у функция перехватчик должна будет загружать прикладные функции, а с внедряемой dll такой проблемы нет.
    Запись от Van111 размещена 03.06.2012 в 16:33 Van111 вне форума
  9. Старый комментарий
    Цитата:
    ну я имел в виду, то что у функция перехватчик должна будет загружать прикладные функции, а с внедряемой dll такой проблемы нет.
    А, ну теперь понятно. Так для сплайсинга, то бишь перехвата с подменой начальных байт функции тоже часто dll внедряется. Основной недостаток сплайсинга, в том, что используется архитектурно зависимый код и для использования на разных архитектурах придётся определять код для каждой. В то время как код с изменением таблицы импорта от этого свободен
    Запись от Subrealist размещена 03.06.2012 в 17:31 Subrealist вне форума
  10. Старый комментарий
    Аватар для ISergey
    Цитата:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    unsigned long WINAPI call_inject_dll(LPVOID lpParameter)
    {
     
    MYPROC fLoadLibraryA;
    (void*)fLoadLibraryA =(void*)0x7c801d7b ;
    fLoadLibraryA(lpParameter);
     
    for(;;){}
    }
    Как-то странновато..

    Мне вот так больше нравится=)
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    
    int InjectDll(HANDLE hProcess, const char *fullPath)
    {
        //char fullPath[MAX_PATH] = "C:\\gssandbox.dll";
        LPVOID libAddr, llParam;
        BOOL wpm;
     
     
        if(!hProcess)
        {
            printf("[!] OpenProcess failed, GLE=%d.\n",
                GetLastError());
            return EXIT_FAILURE;
        }
     
        libAddr = (LPVOID)GetProcAddress(
            GetModuleHandleA("kernel32.dll"),
            "LoadLibraryA");
     
        llParam = (LPVOID)VirtualAllocEx(
            hProcess,
            NULL,
            strlen(fullPath),
            MEM_RESERVE | MEM_COMMIT,
            PAGE_READWRITE);
     
        if(!llParam)
        {
            printf("[!] VirtualAllocEx failed, GLE=%d.\n",
                GetLastError());
            return EXIT_FAILURE;
        }
     
        wpm = WriteProcessMemory(
            hProcess,
            (LPVOID)llParam,
            fullPath,
            strlen(fullPath),
            NULL);
     
        if(!wpm)
        {
            printf("[!] WriteProcessMemory failed, GLE=%d.\n",
                GetLastError());
            return EXIT_FAILURE;
        }
     
        HANDLE crt = CreateRemoteThread(
            hProcess,
            NULL,
            0,
            (LPTHREAD_START_ROUTINE)libAddr,
            (LPVOID)llParam,
            0,
            NULL);
     
        if(!crt)
        {
            printf("[!] CreateRemoteThread failed, GLE=%d.\n",
                GetLastError());
            return EXIT_FAILURE;
        }
     
     
        return EXIT_SUCCESS;
    }
    Запись от ISergey размещена 08.06.2012 в 18:41 ISergey вне форума
  11. Старый комментарий
    ISergey, вообще я сделал немного не правильно мне надо было объявить структуру где хранится строка kernel32 и строка с адресом
    struct data
    {
    char namelibrary[10];
    void* address;
    }my_data={"Kernel32",""} ;
    ...
    дальше где то записываем в эту структуру адрес функции;
    ....
    записываем в выделенную память не строку kernel32 а структуру my_data
    ....

    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    unsigned long WINAPI call_inject_dll(LPVOID lpParameter)
    {
    data *t;
    t=lParameter; 
    MYPROC fLoadLibraryA;
    (void*)fLoadLibraryA =t->address ;
    fLoadLibraryA(t->namelibrary);
    for(;;){}
    }
    текст набирал в блокноте возможны синтаксические ошибки
    Запись от Van111 размещена 09.06.2012 в 13:05 Van111 вне форума
  12. Старый комментарий
    Аватар для Pure
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    void INIT ()
    {
           char s[50];
           GetCurrentProcessName(GetCurrentProcessId()/*передаем ID текущего процесса*/,s);
           HMODULE hmodCaller = GetModuleHandle(s);//по имени текущего процесса получаем хэндл модуля
       
    }
     
    void GetCurrentProcessName(ULONG ID ,LPSTR szExeName)//по id процесса ищется его имя
    {
            PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
            HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
            if(Process32First(hSnapshot, &Pc))
            {
                    do
                    {
                            if(Pc.th32ProcessID==ID)
                            {
                                    strcpy(szExeName,Pc.szExeFile);//если ID совпало копируем имя в буфер
                                    return ;
                            }
                    }
                    while(Process32Next(hSnapshot, &Pc));
            }
    }
    как думаешь код выше можно заменить на просто
    C++
    1
    
    GetModuleHandleA(0);//получаем хэндл текущего модуля
    ?
    Запись от Pure размещена 13.06.2012 в 17:00 Pure вне форума
  13. Старый комментарий
    да можно
    Запись от Van111 размещена 15.06.2012 в 18:05 Van111 вне форума
  14. Старый комментарий
    Аватар для _lucius_
    Subrealist
    Цитата:
    Если секция запрещена для записи, то можно посчитать остающееся свободным место как VirtualSize-RawSize.
    Нельзя так вычеслять! Физический размер может быть больше виртуального! К примеру если виртуальный размер равен нулю загрузчик тогда берёт физический размер секции, округлив его на величину SectionAlignment, а хвост заполняется нулями. Вир. адрес следующей секции равен вир. адресу предыдущей секции плюс ее размер, выровненный на величину SectionAlignment. Т.е. они идут друг за другом (к физ. секциям это не относится). Вот от этого и отталкивайтесь.
    Запись от _lucius_ размещена 26.06.2012 в 10:03 _lucius_ вне форума
  15. Старый комментарий
    Аватар для _lucius_
    Van111
    Цитата:
    по адресу 0x7c801d7b(это функция LoadLibraryA находящаяся в ядре kernel32,её адрес для всех процессов одинаковый)
    Да действительно, её адрес во всех процессах одинаковый. Но то, что он одинаковый на всей NT линейке, не факт! Так что жостко прописывать его в программе нельзя. Нужно получить LoadLibraryA с помощью API или самому из экспорта и передать адрес вместе с кодом для инжекта.
    Запись от _lucius_ размещена 26.06.2012 в 10:16 _lucius_ вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru