Большой Воронежский Форум
» Программирование>нужно расковырять чужой процесс
xxx-men 15:00 14.02.2009
обьясните на простом примере как это происходит.

есть приложение стороннего производителя:
loader.exe
Код:
#include <Windows.h>
#include <iostream>

//--------------------импортируем функции testlib.dll--------------------------
#pragma comment(lib,"..\\debug\\testlib.lib") 
extern "C" int WINAPI test(int x); 
//-----------------------------------------------------------------------------------

int main(char*, char*)
{
	//LoadLibrary(L"patcher.dll"); //какимто волшебным образом грузим патч

	getchar();
	test(0);
	getchar();
	return 0;
};
testlib.dll
Код:
#include <Windows.h>
#include <iostream>

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved)
{	
	return TRUE;
};

extern "C" int WINAPI test(int x) //экспорт
{
        if (x==0)
	    {
		printf("street magic failed\n");
	    }
	else if (x==1)
	   {
		printf("oO pechen'ki \n");
	   }
	else
	   {
		printf("crazy magic \n");
	   };

        return 0;
};
testlib.def
Код:
LIBRARY	"testlib"
EXPORTS
test @666
функция test() из библиотеки testlib.dll в асме выглядит так:
Код:
.text:1001108C                 jmp     test_0    //это возвращает GetProcAddres
..............
......
..............
.text:10011380
.text:10011380 ; =============== S U B R O U T I N E =======================================
.text:10011380
.text:10011380 ; Attributes: bp-based frame
.text:10011380
.text:10011380 test_0          proc near               ; CODE XREF: testj
.text:10011380
.text:10011380 var_C0          = byte ptr -0C0h
.text:10011380 arg_0           = dword ptr  8
.text:10011380
.text:10011380                 push    ebp
.text:10011381                 mov     ebp, esp
.text:10011383                 sub     esp, 0C0h
.text:10011389                 push    ebx
.text:1001138A                 push    esi
.text:1001138B                 push    edi
.text:1001138C                 lea     edi, [ebp+var_C0]
.text:10011392                 mov     ecx, 30h
.text:10011397                 mov     eax, 0CCCCCCCCh
.text:1001139C                 rep stosd
.text:1001139E                 cmp     [ebp+arg_0], 0
.text:100113A2                 jnz     short loc_100113BD
.text:100113A4                 mov     esi, esp
.text:100113A6                 push    offset aStreetMagicFai ; "street magic failed\n"
.text:100113AB                 call    ds:__imp__printf  
.text:100113B1                 add     esp, 4
.text:100113B4                 cmp     esi, esp
.text:100113B6                 call    j__RTC_CheckEsp
.text:100113BB                 jmp     short loc_100113F3
.text:100113BD ; ---------------------------------------------------------------------------
.text:100113BD
.text:100113BD loc_100113BD:                           ; CODE XREF: test_0+22j
.text:100113BD                 cmp     [ebp+arg_0], 1
.text:100113C1                 jnz     short loc_100113DC
.text:100113C3                 mov     esi, esp
.text:100113C5                 push    offset aOoPechenKi ; "oO pechen'ki \n"
.text:100113CA                 call    ds:__imp__printf  ;интересует этот случай
.text:100113D0                 add     esp, 4
.text:100113D3                 cmp     esi, esp
.text:100113D5                 call    j__RTC_CheckEsp
.text:100113DA                 jmp     short loc_100113F3
.text:100113DC ; ---------------------------------------------------------------------------
.text:100113DC
.text:100113DC loc_100113DC:                           ; CODE XREF: test_0+41j
.text:100113DC                 mov     esi, esp
.text:100113DE                 push    offset aCrazyMagic ; "crazy magic \n"
.text:100113E3                 call    ds:__imp__printf
.text:100113E9                 add     esp, 4
.text:100113EC                 cmp     esi, esp
.text:100113EE                 call    j__RTC_CheckEsp
.text:100113F3
.text:100113F3 loc_100113F3:                           ; CODE XREF: test_0+3Bj
.text:100113F3                                         ; test_0+5Aj
.text:100113F3                 xor     eax, eax
.text:100113F5                 pop     edi
.text:100113F6                 pop     esi
.text:100113F7                 pop     ebx
.text:100113F8                 add     esp, 0C0h
.text:100113FE                 cmp     ebp, esp
.text:10011400                 call    j__RTC_CheckEsp
.text:10011405                 mov     esp, ebp
.text:10011407                 pop     ebp
.text:10011408                 retn    4
.text:10011408 test_0          endp
.text:10011408
.text:10011408; ---------------------------------------------------------------------------
далее идет мой код.
задача: заменить нужные вызовы printf на fakeprintf
patcher.dll
Код:
#include <Windows.h>
typedef int (WINAPI *testEx)(int x);

extern "C" int WINAPI fakeprintf(char* data)
{
//тут будут всякие шаманства
//
//
return 0;
};


int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved)
{
	LPWCH name = new WCHAR[MAX_PATH];
	GetModuleFileNameW(0,name, MAX_PATH);
	MessageBox(0,name,L"запустилась",MB_OK);//тут будет проверка name

	HMODULE hlib = GetModuleHandle(L"testlib");
	testEx f =  (testEx)GetProcAddress(hlib,"test");//f=0x1001108C
     //и тут типа закончилась фантазия......
     //......пойду убьюсь

return TRUE;
};
patcher.def
Код:
LIBRARY	"patcher"
EXPORTS
fakeprintf @1
[Ответ]
xxx-men 16:48 14.02.2009
ручками (PEtools) добавляю в таблицу импорта функию fakeprintf из patcher.dll
ручками меняю call ds:__imp__printf на call ds:fakeprintf
заработало.

как эти действия повторить программно?


защита суко после запуска проверяет файлы на изменения. [Ответ]
Part!zan 20:29 16.02.2009
xxx-men, возьми любой патчер, работающей в рантайме (он же - лоадер), их в инете навалом, и сделай в начале честного принтф джамп на свой принтф. [Ответ]
xxx-men 14:51 17.02.2009

Сообщение от Part!zan:
возьми любой патчер, работающей в рантайме (он же - лоадер), их в инете навалом

оО, незнал про такое.
upd: чо написать в поисковике, чтобы он суко выдал то что надо?)))

Сообщение от Part!zan:
сделай в начале честного принтф джамп на свой принтф.

1)допустим приложение в многих местах вызывает подопытную функцию, а меня интересует только один случай, неочень бы хотелось(вдруг будет вообще невозможно) фильтровать не нужные вызовы по параметрам.
2)скорее всего придеца работать в агресивной среде, где многа кулхацкерского софта ставят какие нибуть джампы. возможны конфликты. [Ответ]
Part!zan 19:20 17.02.2009

Сообщение от xxx-men:
чо написать в поисковике

process patcher

Сообщение от xxx-men:
меня интересует только один случай

Ну, тогда, конечно, проще исправить только конкретный вызов. Кстати, не вижу проблем с анализом параметров - тебе достаточно только проверить откуда в тебя перешли, глянув в стек, ты же знаешь адрес нужного тебе места...

Сообщение от xxx-men:
придеца работать в агресивной среде, где многа кулхацкерского софта

а подробнее? [Ответ]
xxx-men 18:29 18.02.2009

Сообщение от Part!zan:
достаточно только проверить откуда в тебя перешли, глянув в стек, ты же знаешь адрес нужного тебе места...

согласен, но всеравно больше кода -> больше глюков

Сообщение от Part!zan:
а подробнее?

мне нужны функции send\recv из wsock32.dll, просто на printf тренеруюсь

защита грузит клиента,
прячет его (если не стоит каспер),
открывает рандомные порты,
волшебным образом разворачивает трафик на них,
при конекте к этим портам проверяет определенные файлы клиента на изменения
криптует(суко) трафик и шлет серверу.

примерно через 15-20 секунд(типа запас времени дали) после старта, клиент запускает >>>это<<<
гамно редкосное, делает обвертки на все что знает, включая функции ядра, сбрасывает хуки(?)
начинаюца глюки usb клавиатур\мышек, орут матом антивири\фаерволы,
перестают работать студия и другие отладчики, в тяжких случаях qip,
у самых везучих падает vpn (если не стоит каспер).

вот примерно с этим возможны конфликты....
[Ответ]
Part!zan 19:27 18.02.2009
xxx-men, имхо, с таким ... бороться - только наживать геморрою. Раз это практически руткит, то обмануть его будет нелегко. Проще, наверное, эмулятор написать ) [Ответ]
xxx-men 19:54 18.02.2009
что ты имееш в виду под "таким"?

если это:

Сообщение от xxx-men:
защита грузит .....

тупо прокладка_шифровалка между клиентом и сервером, с мелкими но подлыми пакостями (если накатаеш эмулятор без этих "мелких пакостей", я знаю куда его дорого продать)

или ты про это:

Сообщение от xxx-men:
гамно редкосное.....

так тут все шоколадно, в клиент из вне никто не влезет (хотя это должно сработать)
а вот внутренние потоки клиента могут делать что хотят. [Ответ]
Part!zan 19:13 19.02.2009
xxx-men, че-то я совсем потерял нить беседы: зачем тебе перехватывать функции winsock, с кем, из двух перечисленных, ты собрался бороться? [Ответ]
дядя Дима 10:57 20.02.2009
нда, отдел К не спить -))))))) [Ответ]
xxx-men 21:04 20.02.2009

Сообщение от Part!zan:
с кем, из двух перечисленных, ты собрался бороться?

я собрался с ними мирно сосуществовать.



появилась проблема
в тесте было так:
Код:
.100113CA  FF156C820110      call      printf ; MSVCR80D.dll
в то что выделенно жирным пишеш результат GetProcAddress(hmylib,"fakeprintf") и все работает.


а в реальном случае такая хрень:
Код:
0000A4D2: FF2528397210                 jmp       d,[10723928]; джамп на send из wsock32
---
-
---
00015BBB: 50                           push      eax
00015BBC: 51                           push      ecx
00015BBD: E81049FFFF                   call      00000A4D2 ; нужный вызов
00015BC2: 8BF0                         mov       esi,eax
инструкция call имеет длинну 5 байт, типа "короткий переход"?
все send вызывают этот джамп.
свободного места для добавления своего jmp по близости не обнаружил
править jmp скорее всего не выдет

как в этой ситуации нарулить вызов на себя? [Ответ]
Part!zan 11:33 21.02.2009
Обычно, при вызове библиотечной функции, делается call на этот джамп. Правь его. [Ответ]
xxx-men 17:55 22.02.2009

Сообщение от Part!zan:
Правь его.

его не только я правлю, но вроде все разрулил=)


как заставить библиотеку выгрузить саму себя? [Ответ]
Part!zan 00:00 23.02.2009
xxx-men, выгружает тот, кто подгружал. [Ответ]
Вверх