PDA

Просмотр полной версии : вызов функций


goodvin1709
12.01.2013, 00:08
Вот мне интересно,кто может помогите с исходниками,набросками,интересными статьями и мыслями,как вызывать функции и как работать с ними не через пакеты,а прямо с API клиента,не актуально уже стало работать с пакетами после того как почти все сервера начинают вводить шифр,писание алгоритмов занимает очень много времени,а вот как работать с вызовом функций,перехватом функций,подключением к клиенту своих программ думаю не только мне будет интересно.Реально ли так создать базу инвентаря в другой программе,список NPC вокруг чара,и получения другой информации с помощью API,какие библиотеки перехватывать.Короче всю интересную информацию связаную с этим постите ниже..Спасибо зарание.

maxilam
12.01.2013, 00:43
.Реально ли так создать...
реально. делал полноценного бота под руофф на АПИ клиента. Заморочек там не меньше чем при перехвате и дешифрации пакетов. Нужно найти функцию отвечающую за то или иное действие (методом научного тыка, благо названия у функций в большинстве своем говорящие), определить параметры которые ей передаются (в качестве параметров бывают целые классы, например L2ParamStack, до сих пор с ужасом о нем вспоминаю), хукнуть эту функцию если требуется.
И так на каждое действие, приходится искать соответствующую функцию и обрабатывать ее. И еще куча подводных камней, сейчас уже и не вспомнишь все.
Почитай тут (http://coderx.ru/showthread.php?t=1077), много чего можно узнать.

Две DLL из которых импортируются необходимые функции: Engine.dll и Core.dll. Открой Engine.dll в IDA Pro, посмотри список экспортируемых функций. Классы, с которыми придется работать это UGameEngine и UNetworkHandler: первый класс для получения состояния игрового мира, второй для воздействия на игровой мир. Core.dll уже не вспомню на вскидку, что импортирует.

В общем можно писать целую докторскую диссертацию по работе с АПИ клиента )))

Morfik
12.01.2013, 01:04
goodvin1709, там тем по этой теме хватает http://coderx.ru/forumdisplay.php?f=35 , например сразу вот http://coderx.ru/showthread.php?t=948

goodvin1709
12.01.2013, 02:38
Решил попробовать подцепить L2CC тут на форуме лежала Работает скажу отлично хоть и на сервере стоит защита(Шифрация и всякая другая дрянь) хоть вдохновило то что она работает.
[Просмотр файла только для зарегистрированных пользователей...]
Теперь бы это сделать в делфи хоть бы 1 пример перехвата функции или как создать хоть список чаров вокруг персонажа и вывести их в listbox

St1mul
12.01.2013, 13:33
Теперь бы это сделать в делфи хоть бы 1 пример перехвата функции или как создать хоть список чаров вокруг персонажа и вывести их в listbox
От xkor'a
дельфи не умеет работать с thiscall типом вызова вроде, так что надо будет всё равно переходники на асме делать...
Ps ты мне скажи что за бред это на интерлюде где онлайн +100500 работает л2сс
а на какой то ГФШ типа http://gastia.ru/index.php он не работает, там GG палит если хоть на 1 байт изменен размер екзешника или дллки которые к нему подключатся.
не актуально уже стало работать с пакетами после того как почти все сервера начинают вводить шифр,
Вот если сейчас здесь напишем как работать с хуками - история опять повторится и гфш всякие будут вводит зашиты, чтобы никто не мог хукать апи функции. Появился l2phx в широком пользовании - все сервера стали вводить шифрацию, появятся программы ставящие хуки на Апи функции появятся и защиты.
P.S.S. Сделай другой скрин, чтобы не было видно

maxilam
12.01.2013, 14:37
Теперь бы это сделать в делфи хоть бы 1 пример перехвата функции или как создать хоть список чаров вокруг персонажа и вывести их в listbox

http://coderx.ru/showpost.php?p=171667&postcount=425

Как то так. Прочитай ту тему от и до, многое станет понятным. Все зависит от твоего знания дельфей, от сервера под который делаешь перехват, от понимания методов сплайсинга функций. А готовые сорцы навряд ли тебе выложат )).

goodvin1709
12.01.2013, 17:58
Да теперь я понял как перехватить
procedure OnUserInfo_Hook(user: pointer; x,y,z: single; u1,u2,u3: single; s1,s2: integer); stdcall;
asm
push s2;
push s1;
push u3;
push u2;
push u1;
push z;
push y;
push x;
push user;
push ecx;
call OnUserInfo_New;
end;
Это мы перехватили функцию. и вызываем OnUserInfo_New;
procedure OnUserInfo_New(h: integer; user: pointer; x,y,z: single; u1,u2,u3: single; s1,s2: integer); stdcall;
begin
...
//делаем свои делишки
...
OnUserInfo_Call(user, x,y,z, u1,u2,u3, s1,s2);
end;
тут мы изменяем я так и не понял что вот только что вызываем функцию
OnUserInfo_Call(user, x,y,z, u1,u2,u3, s1,s2);
procedure OnUserInfo_Call(user: pointer; x,y,z: single; u1,u2,u3: single; s1,s2: integer); stdcall;
asm
push s2;
push s1;
push u3;
push u2;
push u1;
push z;
push y;
push x;
push user;
mov ecx, geh;
mov esp, ebp;
pop ebp;
jmp [OnUserInfo_Original];
end;
а тут мы отправили на API
Верно?
Теперь научиться бы иньектить свою ДЛЛ,форму вызвать не тежело из Длл,а вот сделать что бы хукала хоть что то и передавала в форму это уже был бы прогресс.Да тут можна начать работать с новыми видами ботов,уже не пакетными а АРІ просто сюда не вылаживать готовый продукт.

maxilam
12.01.2013, 18:57
...
//делаем свои делишки
...
тут ни чего изменять не надо, просто получаем данные о чаре и пересылаем любым удобным способом во внешнюю программу.
user: pointer указатель на структуру User содержащую всю информацию о твоем чаре (в Engine.dll есть две функции UserInfо и CharInfo. Первая отвечает за твоего чара, другая за всех остальных чаров вокруг, за NPC отвечает другая функция). x,y,z - координаты чара.
Кстати со структурой User тоже придется попотеть, и собирать ее по крупицам из байтов дампа, если же конечно кто то это не сделал до тебя, именно под нужные тебе хроники
По поводу инжекта погугли: SetWindowsHookEx

goodvin1709
12.01.2013, 19:22
Спасибо добрый дядя

Добавлено через 22 минуты
HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId);
idHook=WH_DEBUG
lpfn - Указатель на функцию ловушки.lpfn должен указывать на процедуру ловушки в динамически закгружаемой библиотеке (DLL).
hmod - Дескриптор DLL, содержащей функцию, указанную в параметре lpfn.
dwThreadId -Идентификатор потока, в котором необходимо перехватывать сообщения.
Наверное есть у кого то примерчик по даной процедуре?

St1mul
12.01.2013, 19:43
Я могу подкинуть.В зависимости от того как ты хочешь оформить хук.
Скажи какой именно:
1.Хочешь поставить хук в длл и приатачить длл в екзешник. (как л2сс)
2. Хочешь поставить хук, когда процесс ла2 уже запущен

goodvin1709
13.01.2013, 01:32
думаю второй т.к есть моменты когда не всегда хочешь зайти с хуком. Ну и цеплять к .екзешнику думаю будет палевно. А то всякие защиты от проверки длл. Хотя с каким легче работать.

St1mul
13.01.2013, 07:06
Вот темка (http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces)на английском про инжект
Вот пример проги которая инжектися к explorer.exe и меняет левую кнопку с правой при нажатии кнопки пуск
Я пытался переделать ее на фасм но как то не получилось и после 3х дней мучений бросил эту затею

St1mul
13.01.2013, 08:09
Ps до сих пор не могу понять что делает функция DisableThreadLibraryCalls
может кто объяснить?

SeregaZ
13.01.2013, 08:58
а если перевести название дословно? типа "отключение вызова библиотеки в потоке"?

Demion
13.01.2013, 09:17
А что на MSDN не понятно? Не вызывает DllMain с значениями параметра fdwReason DLL_THREAD_ATTACH и DLL_THREAD_DETACH. По умолчанию DllMain вызывается с этими параметрами, когда процесс создает и уничтожает поток соответственно.

И так же не понял по какой причине в ла2 не должен работать метод внедрения кода через CreateRemoteThread и WriteProcessMemory. У меня все работает. Или речь идет о какой-то определенной защите на сервере?

St1mul
13.01.2013, 12:02
1) У меня при получение потока с помощью CreateRemoteThread, сразу же выдает крит и пишет что core.dll или engine.dll че-нибудь не могут сделать. Сервер обычная гфш
2) DisableThreadLibraryCalls как я понял убирает функцию повторного вызова DllMain, когда мы закрываем ла2.

mira
13.01.2013, 12:23
DisableThreadLibraryCalls запрещает вызовы длл-майн другими потоками процесса с параметром THREAD_ATTACH.
а при загрузке длл и ее выгрузке она вызывается всегда :)
обычным приложениям не создающим 100500 потоков в минуту этот параметр не существенен ИМХО.
как правило THREAD_ATTACH всеравно никто не обрабатывает.

Добавлено через 2 минуты
думаю второй т.к есть моменты когда не всегда хочешь зайти с хуком. Ну и цеплять к .екзешнику думаю будет палевно. А то всякие защиты от проверки длл. Хотя с каким легче работать.

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

St1mul
13.01.2013, 12:35
Ну раз специалисты по ассемблеру собрались осмелюсь задать такой вопрос: Когда мы устанавливаем ловушку SetWidowsHookEx на чужой поток мы должны будем поместить процедуру нашего фильтра( обработчик сообщений) в длл. Скажите, что должна содержать процедура фильтра и что она должна возвращать?
У меня есть приложение и я хочу поставить ловушку сообщений, все делаю как надо SetWindowsHookEx возвращает не ноль, но когда хук срабатывает( я посылаю сообщение приложению, на которое поставлен хук) в приложении, само приложение критует

Demion
13.01.2013, 13:31
1) У меня при получение потока с помощью CreateRemoteThread, сразу же выдает крит и пишет что core.dll или engine.dll че-нибудь не могут сделать. Сервер обычная гфш

Покажи код, так сложно гадать.

2) DisableThreadLibraryCalls как я понял убирает функцию повторного вызова DllMain, когда мы закрываем ла2.

Нет. DllMain будет вызываться, когда длл загружается (внедряется) и когда выгружается. DisableThreadLibraryCalls запрещает вызов DllMain, когда приложение запускает и завершает новый поток.

St1mul
13.01.2013, 13:37
Я бросил уже затею с получением потока.
Выложи лучше ты свои, если у тебя получилось
Вот недоделанные исходники на FASM c SetWindowsHookEx
exe:
format pe gui 4.0
entry start
include 'win32a.inc'
ThreadID = 2004 ; - поток на который хотим поставить ловушку
section '.data' data readable writeable
Name1 db 'Hook.dll',0
Hook dd ?
Name2 db 'Hook.txt',0
Handle2 dd ?
var1 dd ?
msg1 db 'Prees to unhook',0
msg2 db 'Hook',0
section '.code' code readable executable
start:
invoke GetModuleHandleA,Name1
invoke SetWindowsHookExA,WH_KEYBOARD,Hooking,eax,ThreadID
mov [Hook],eax
invoke CreateFileA,Name2,GENERIC_WRITE,FILE_SHARE_WRITE,0 ,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
mov [Handle2],eax
invoke WriteFile,eax,Hook,4,var1,0
mov eax,[Handle2]
invoke CloseHandle,eax
invoke MessageBoxA,0,msg1,msg2,MB_OK
mov eax,[Hook]
invoke UnhookWindowsHookEx,eax
invoke ExitProcess,0

section '.idata' import data readable writeable
library kernel32,'kernel32.dll',\
user32,'user32.dll',\
Hook,'Hook.dll'
import kernel32,\
ExitProcess,'ExitProcess',\
GetModuleHandleA,'GetModuleHandleA',\
LoadLibraryA,'LoadLibraryA',\
CreateFileA,'CreateFileA',\
WriteFile,'WriteFile',\
GetProcAddress,'GetProcAddress',\
CloseHandle,'CloseHandle',\
GetCurrentThreadId,'GetCurrentThreadId'
import user32,\
MessageBoxA,'MessageBoxA',\
SetWindowsHookExA,'SetWindowsHookExA',\
UnhookWindowsHookEx,'UnhookWindowsHookEx'
import Hook,\
Hooking,'Hooking'
DLL:
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32a.inc'
section '.data' data readable writeable
msg db 'Hook works',0
msg1 db 'Nice',0
Name1 db 'Hook.txt',0
var1 dd ?
Hook dd ?
var2 dd ?
Name2 db 'Hook.dll',0
LRESULT dd ?

section '.code' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
cmp [fdwReason],1
jnz bad
mov eax,[hinstDLL]
invoke DisableThreadLibraryCalls,eax
jmp bad
bad:
mov eax,1
pop ebp
ret 12
endp
;================================================= ========

proc Hooking stdcall nCode,wparam,lparam
invoke MessageBox,0,msg,msg1,MB_OK
invoke OpenFile,Name1,var1,OF_READ
invoke ReadFile,eax,Hook,4,0,0
mov ebx,[Hook]
mov eax,[nCode]
mov ecx,[wparam]
mov edx,[lparam]
invoke CallNextHookEx,ebx,eax,ecx,edx
mov [LRESULT],eax
ret
endp
;================================================= =========

section '.idata' import data readable writeable
library kernel32,'kernel32.dll',\
user32,'user32.dll'
import kernel32,\
ExitProcess,'ExitProcess',\
LoadLibraryA,'LoadLibraryA',\
GetModuleHandleA,'GetModuleHandleA',\
FreeLibrary,'FreeLibrary',\
OpenFile,'OpenFile',\
ReadFile,'ReadFile',\
DisableThreadLibraryCalls,'DisableThreadLibraryCal ls'
import user32,\
MessageBox,'MessageBoxA',\
UnhookWindowsHookEx,'UnhookWindowsHookEx',\
RegisterWindowMessageA,'RegisterWindowMessageA',\
CallNextHookEx,'CallNextHookEx'


;================================================= =========
section '.edata' export data readable
export 'Hook.DLL',\
Hooking,'Hooking'
dd LRESULT

section '.reloc' fixups data discardable
ThreadID можно получить с помощью WinSpy (в атаче ) Переводим из 16ричной системы в 10 и записываем в екзешник в константу ThreadId

Demion
13.01.2013, 13:54
Собрал "на коленке" только что. Вроде все работает, клиента ла2 проверить нет. Путь нужно указывать полный ("C:\\Library.dll") либо длл должна находится в Working Directory приложения (обычно около самого приложения). А так вообще готовых решений и примеров полно в интернете. Тема не редкая.
http://pastebin.com/y6q88adp

goodvin1709
13.01.2013, 23:10
Жаль что все исходники в С++ а не делфе( может делфи наброски будут?

Demion
14.01.2013, 04:53
Не сильно то отличается от сишного кода :)

http://pastebin.com/0b43ha6d

St1mul
14.01.2013, 06:29
Еще один вопрос специалистам: как вы выковыриваете функции
Вот хоть убейте IDA не может найти UnetworkHandler::Say2
она как бы его видит и показывает в списках экспорта, но на месте которое указано какие то левые байты.
Я так предполагаю, что это из за TheMida компресии
Есть ли какие то особые настройки у гуру? или же плагины?

Demion
14.01.2013, 06:40
А что ты именно хочешь узнать? Параметры экспортируемой функции?

St1mul
14.01.2013, 06:46
А что ты именно хочешь узнать? Параметры экспортируемой функции?
нет, я хочу узнать действия совершаемые этой функцией
параметры написаны в скобочках, че их искать
еще бы мне кто объяснил мне боту, как посмотреть древо вызовов: откуда могут совершать jmp и помещать в стек адрес начала функции

Demion
14.01.2013, 07:16
Я думал, что экспортные функции отображены в декорированном виде (?Foooo@@YAXXZ).

Адрес возврата лежит в стеке над параметрами (EBP + 4). Функции вызываются с помощью call, не jmp, если я правильно понял о чем речь.

Полагаю, чтобы работать с длл в дизассемблере, она должна быть распакована.
http://fyyre.ivory-tower.de/ - здесь можно поискать некоторые распакованные библиотеки некоторых хроник.
В принципе имплементация каких-то основных методов, может не меняться от хроник в хроники.

maxilam
14.01.2013, 08:40
Я думал, что экспортные функции отображены в декорированном виде (?Foooo@@YAXXZ).
так и есть. но этого достаточно для работы с ними.

GetNextCreature_Original:= GetProcAddress(hMod,'?GetNextCreature@UNetworkHand ler@@UAEPAUUser@@MH@Z');

все экспортируемые функции и их параметры можно посмотреть в IDAPro не снимая защиты с длл

Вкладка Exports в IDAPro
2792
Сразу видно что в качестве параметра нужно передать указатель на L2ParamStack. А что там выполняется с ним дальше, для написания бота знать не обязательно ;)

Вкладка IDA View-A, откуда и берем декорированое имя функции для импорта в нашу длл
2793

Demion
14.01.2013, 08:42
но этого достаточно для работы с ними.
И как ты узнаешь параметры функции не расшифровав декорированное название? :D

Кроме того их можно расшифровать с помощью винапи UnDecorateSymbolName или с помощью тулзы Microsoft C++ Name Undecorator (undname.exe), которая идет с Visual Studio.

maxilam
14.01.2013, 09:10
И как ты узнаешь параметры функции не расшифровав декорированное название?
Demion, дополнил ответом свой предыдущий пост

Demion
14.01.2013, 09:39
Demion, дополнил ответом свой предыдущий пост

Спасибо конечно, но по-моему суть не в этом. Я сам то знаю как получить параметры функции и как расшифровать ее название. Дело в том, что только декорированного вида никак не хватает, для работы с функцией. А как ее расшифровывать не важно. В данном случае, ты расшифровываешь с помощью IDA. Можно с помощью undname или WinAPI.

maxilam
14.01.2013, 09:42
декорированного вида никак не хватает, для работы с функцией
я не знаю как там в ассемблере, но в дельфях этого хватает сполна.
увы, тогда я тут уже не помощник )))

Demion
14.01.2013, 09:46
я не знаю как там в ассемблере, но в дельфях этого хватает сполна.
увы, тогда я тут уже не помощник )))

Что-то мы о разных вещах говорим. Под "работы с функцией" я подразумевал, что чтобы вызывать функцию, нужно знать ее параметры. А чтобы знать ее параметры, нужно расшифровать ее название до нормального вида. Из этого вывод, что только декорированного вида для работы не хватает.

В любом случае, заканчиваю этот "флуд".

St1mul
14.01.2013, 14:39
maxilam, у тебя какая IDA?
проблема в том, что во в вкладке View A левые байты
залей твой engine.dll сюда если не сложно, и ссылку на твою IDA

Попробую по другому написать рукописную программу считывающую байты с адресса функции и потом записывающую в txt файл

mira
14.01.2013, 15:01
Я бросил уже затею с получением потока.
ThreadID можно получить с помощью WinSpy (в атаче ) Переводим из 16ричной системы в 10 и записываем в екзешник в константу ThreadId
очень умно задавать переменную ядра ОС как константу :D

Добавлено через 5 минут
так и есть. но этого достаточно для работы с ними.
[CODE]

Сразу видно что в качестве параметра нужно передать указатель на L2ParamStack. А что там выполняется с ним дальше, для написания бота знать не обязательно ;)

Вкладка IDA View-A, откуда и берем декорированое имя функции для импорта в нашу длл
2793

там почти все функции принимают единственный агрумент - парамстек) это чето типа класса-обертки для массива параметров.

maxilam
14.01.2013, 15:39
engine.dll с текущих хроник руоффа (как есть, без какой либо дешифрации, без снятия защиты, порчи, сглаза, приворота и еще чего там иннова вешает на свои файлы :D )
http://rghost.ru/43019527

ida скачана с торрентов, уже не помню точно откуда
2795

Guzh
14.01.2013, 17:48
Зачем искать где-то распакованные дллки, если можно просто снять дамп уже распакованного в памяти библиотеки. Я так всегда делаю.

St1mul
14.01.2013, 17:50
Зачем искать где-то распакованные дллки, если можно просто снять дамп уже распакованного в памяти библиотеки. Я так всегда делаю.
а IAT вы как простите хотите востанавливать?

Guzh
14.01.2013, 17:58
А зачем его восстанавливать? Для изучения работы длл хватает и того что есть, ведь дамп сделан для изучения дллки,а не изменения с последующей заменой. IDA со всем справляется,главное задать ему адрес в который была загружена дллка. Правда с импортируемыми функциями немного сложнее будет - ручками придется изменять/добавлять названия

St1mul
14.01.2013, 17:58
Неужели заработало
Приношу свои извенения Guzh, не поверил, что IDA может анализировать нерабочую dll

goodvin1709
17.01.2013, 22:25
http://www.programmersclub.ru/gruzin-api-perhvat/ Вот статья с хуком на делфи,кто может запилить что то подобное только для L2 и перехватом только 1 функции а то невыходит нихрена.

Sherman
18.01.2013, 19:25
В примере же все разжевано.

St1mul
23.01.2013, 14:29
Кто может показать название пакета EnterWorld в engine.dll?

maxilam
23.01.2013, 18:14
UGameEngine::RequestEnterWorld(void)
эта функция обрабатывается, когда заходишь в игровой мир

UNetworkHandler::RequestEnterWorldPacket(int, int *, unsigned long, unsigned long, unsigned long, unsigned long)
а вызовом этой функций можно зайти в игровой мир
ЗЫ:
название пакета
не пакета, а функции

St1mul
23.01.2013, 21:12
Сообщение от St1mul Посмотреть сообщение
название пакета
не пакета, а функции
Я имел ввиду пакет EnterWorld в l2phx и ему соответствующая функция в engine.dll
Огромное спасибо

Добавлено через 43 минуты
P.S. А пакета Appearing можете подсказать соответствующую функцию?

St1mul
25.01.2013, 23:48
ну же ап люди, кто знает

Guzh
28.01.2013, 10:55
P.S. А пакета Appearing можете подсказать соответствующую функцию?
SAP@UNetworkHandler@@UAEXXZ

St1mul
30.01.2013, 11:06
И еще один вопрос: пакетные функции работают с помощью UnetworkHandler'a , а как вызвать графические? например как открыть инвентарь или макросы?

mira
31.01.2013, 11:14
И еще один вопрос: пакетные функции работают с помощью UnetworkHandler'a , а как вызвать графические? например как открыть инвентарь или макросы?

RequestItemList или его "нетворкхандлерная функция - обертка".

St1mul
31.01.2013, 14:32
Меня интересует именно графически: вот из клиента нажимаем на кнопку инвентаря, и он открывается, при этом никакого пакета не перехватывается
Какая функция это?
P.S. или хотя бы функцию открытия помощи ( справа в низу в меню - помощь)

SeregaZ
31.01.2013, 15:35
я полагаю кнопку открытия инвентаря разрабы упразднили. всмысле не сам инвентарь - а движение пакетов. в С4 все было просто - кнопка инвентаря, и каждый раз приходил боооооооооооольшой пакет с описанием всего содержимого - айди по базе, айди по серверу, количество, какие-то условности типа заточки, и тому подобное. пакет довольно таки большой. в теории, если сто человек устроят флеш моб, открывая инвентарь на раз-два-три могут устроить кратковременный лаг :)

поэтому видимо содержимое инвентаря приходит при входе в мир, а после отслеживаются лишь его модификации - типа соска потратилась, адена прибавилась при поднятии дропа, и тому подобное. и уже сам клиент ведет бухгалтерию что пришло\ушло, а после уже по тыканию инвентаря - показывает внутреннюю бухгалтерию визуально. в интерлюде помница чтобы рефрешнуть инвентарь - то есть заставить сервер послать тебе полностью пакет инвентаря - надо было тыкнуть Таб по моему... причем еще раза два. видимо аналогичная фигня используется и в новых хрониках.

St1mul
03.02.2013, 13:52
Всем спасибо, кто тут отвечает
Но вот проблема все это бесполезно против защиты, которая смотрит чек сумму файлов.
Но это еще решаемая проблема, пишем самый простой инжектор НО! при создание своего потока игра ждет секунды 3-4 и закрывается, при этом не посылается ни одного пакета.
Возможно защита сканирует все потоки и при появление нового закрывается
Мои предположения:
в файлах есть GG закриптованый WinLicense - думаю что это он
Мои предложения:
так как для создания ДиалогБокса нужен поток, можно приатачится к чужому, только вот не знаю какая Api функция может показать мне список активных потоков, кто знает напишите сюда
Кто сталкивался с этим?

Morfik
03.02.2013, 14:06
St1mul,
Уведомление DLL_THREAD_ATTACH

Когда в процессе создается новый поток, система просматривает все DLL, спроецированные в данный момент на адресное пространство этого процесса, и в каждой из таких DLL вызывает DllMain со значением DLL_THREAD_ATTACH. Тем самым она уведомляет DLL-модули о необходимости инициализации, связанной с данным потоком. Только что созданный поток отвечает за выполнение кода в функциях DllMain всех
это про то как могут отслеживать создание потока, + в этот момент могут и хукать CreateThread и отслеживать адресс нового потока - и как то думать - все ок или чит

St1mul
03.02.2013, 15:01
Проблема 100% в том, что защита палит новый созданный поток, я это определил так:
1. Создал инжектор на основе глобального хука WH_KEYBOARD
2. Первый раз в процедуру обработки хука я написал вызов МеседжБокса
3. Спровоцировал вызов хук процедуры в игре, нажатим клавиши
4. Мне выдало месседжбокс и после нажатия кнопки ОК все работала успешно
Второй раз я написал в процедуру обработки хука вызов апи функции LoadLibraryA, которая загружала другую dll с ДиалогБоксом
Но на этот раз у меня окно с линейкой вылетало
;------------------------------------------------------------------------
нашел код на дельфи (http://minichden.narod.ru/articles/delphi/016.htm), который считывает потоки процесса, кто может его разобрать и сказать схему разбора 9 в дельфи не силен ;(

Morfik
03.02.2013, 18:13
St1mul, как ты собрался аттачится к уже существующему потоку? Ты получил список потоков - ты собираешься как то переключить поток и заставить использовать его свой код? (впервые слышу о такой идеи, хотя возможность и не исключена)

Я бы предположил такой вариант обхода - найти длл которая отслеживает потоки и отключить для нее уведомления (что то типа DisableThreadLibraryCalls) и проверить нету ли хуков на CreateThread и его производные и если есть то снять их

St1mul
03.02.2013, 18:33
Суть такая: Устанавливаешь хук например на клавиатуру( как в примере ), и если пользователь нажал клавишу, например Enter, то к программе будет приатаченна длл с твоей процедурой обработки. Она будет автоматически отатачена когда процедура обработки закончится. В процедуру обработки вписываешь LoadLibrary и вот он успех: длл будет приатачена к приложению
FASM (.exe)
format pe gui 4.0
entry start
include 'win32a.inc'
section '.data' data readable writeable

Dll_Name db 'Hook.dll',0
msg db 'good',0

section '.code' code readable executable
start:
invoke GetModuleHandleA,Dll_Name
invoke SetWindowsHookExA,WH_KEYBOARD,Hooking,eax,0
invoke MessageBoxA,0,msg,msg,MB_OK
invoke ExitProcess,0
Fasm (.dll)
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32a.inc'
section '.data' data readable writeable
msg db 'Hook Works!',0
msg1 db 'Nice',0
section '.code' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
invoke DisableThreadLibraryCalls,[hinstDLL]
invoke MessageBox,0,msg,msg1,MB_OK
mov eax,1
ret
endp
proc Hooking
ret
endp
В атаче добавил скомпилинные исходники
Как использовать
1 Запустить 1.exe
2 Нажать 1 раз Ок
3 В любом приложении нажать кнопку клавиатуры.
4 Посмотреть через PETool что к этому приложению будет приатачена Hook.dll
5 Нажать остальные кнопки Ок
P.S. Щас попробую присвоить создаваемый поток engine.dll с помощью GetModuleHandleA
Отключить уведомления к сожалению не вариант, т к в этой dll еще и шифрация вроде бы
Вопрос: а как проверить есть ли хуки на CreateThread

Morfik
03.02.2013, 20:22
St1mul, выложи код с которым происходит вылет игры

St1mul
03.02.2013, 22:00
l2cc - это длл голдфинча,
сервер старсэйдж
проверял на других серверах без защиты - работает идеально
Fasm (.exe)
format pe gui 4.0
entry start
include 'win32a.inc'
section '.data' data readable writeable

Dll_Name db 'Hook.dll',0
msg db 'good',0

section '.code' code readable executable
start:
invoke GetModuleHandleA,Dll_Name
invoke SetWindowsHookExA,WH_KEYBOARD,Hooking,eax,0
invoke MessageBoxA,0,msg,msg,MB_OK
invoke ExitProcess,0

section '.idata' import data readable writeable
library kernel32,'kernel32.dll',\
user32,'user32.dll',\
Hook,'Hook.dll'

import kernel32,\
ExitProcess,'ExitProcess',\
GetModuleHandleA,'GetModuleHandleA',\
CreateThread,'CreateThread'
import user32,\
MessageBoxA,'MessageBoxA',\
SetWindowsHookExA,'SetWindowsHookExA'
import Hook,\
Hooking,'Hooking'
Fasm (.dll)
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32a.inc'
section '.data' data readable writeable
DllName db 'l2cc.dll',0
section '.code' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
invoke DisableThreadLibraryCalls,[hinstDLL]
invoke LoadLibraryA,DllName
mov eax,1
ret
endp
;================================================= ========
proc Hooking
start:
invoke GetModuleHandleA,DllName
ret
endp
;================================================= =========

section '.idata' import data readable writeable
library kernel32,'kernel32.dll'
import kernel32,\
GetModuleHandleA,'GetModuleHandleA',\
LoadLibraryA,'LoadLibraryA',\
DisableThreadLibraryCalls,'DisableThreadLibraryCal ls'



;================================================= =========
section '.edata' export data readable
export 'Hook.DLL',\
Hooking,'Hooking'
dd 0
section '.reloc' fixups data discardable

Demion
03.02.2013, 22:13
St1mul, как ты собрался аттачится к уже существующему потоку? Ты получил список потоков - ты собираешься как то переключить поток и заставить использовать его свой код? (впервые слышу о такой идеи, хотя возможность и не исключена)


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

Если память не изменяет, то можно воплотить это с помощью SetThreadContext и изменение EIP (instruction pointer) регистра потока.

St1mul
03.02.2013, 23:27
Demion, Пожалуйста чуть чуть поподробней напиши, я попытался сделать так
1. Длл с хук процедурой загружается
2. Получаем хэндл engine.dll (GetModuleHandleA)
3. Создаем поток с параметром из пункта 2 (CreateThread )
4. Длл с хук процедурой выгружается
и приложение критует( и так любое приложение критует

Sherman
04.02.2013, 09:24
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
invoke DisableThreadLibraryCalls,[hinstDLL]
invoke LoadLibraryA,DllName
mov eax,1
ret
endp

Красным помечено непонятное место. Зачем ты dll ку заставляешь себя же загрузить, из функции которая отрабатывает когда ты ее подгружаешь (выгружаешь)

St1mul
04.02.2013, 15:21
l2cc это другая dll с хуком на функции engine.dll

Sherman
04.02.2013, 17:32
Следовательно не хватает листинга третьей длл

St1mul
04.02.2013, 19:07
Следовательно не хватает листинга третьей длл
что простите?

Sherman
04.02.2013, 20:21
что простите?
2cc это другая dll с хуком на функции engine.dll
Ее не видно.

St1mul
04.02.2013, 22:18
видно ее и она подключается ( визуально можно увидеть ДиалогБокс)

Sherman
04.02.2013, 22:54
А, туплю

St1mul
05.02.2013, 15:30
Выяснил причину: когда в Dllmain доходит до ret, dll автоматически выгружается (особенность хуков SetWindowsHookEx), а т.к. мы создали поток относящийся к этой dll он и критует

Morfik
05.02.2013, 16:27
St1mul, не выгружай длл, используй для хука не клавиатуру а WH_CALLWNDPROC, но не забывай в длл передавать хуки дальше по цепочке

St1mul
08.02.2013, 20:48
Ни фига не получается, решил сделать немного по-другому:
схема такова: 1)хук -> 2)поиск потоков текущего -> 3)заставляем поток engine или core выполнить наши команды -> 4) выходим из хук процедуры
Застрял на 2, не могу получить список потоков системы, в отладчике постоянно пишет после Thread32First - Error_bad_length
FASM:
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32a.inc'
struct PROCESSENTRY32
dwSize dd ?
cntUsage dd ?
th32ProcessID dd ?
th32DefaultHeapID dd ?
th32ModuleID dd ?
cntThreads dd ?
th32ParentProcessID dd ?
pcPriClassBase dd ?
dwFlags dd ?
szExeFile rb 260h
ends
section '.data' data readable writeable
Handle dd ?
DllName db 'One.dll',0
msg db 'Hook works!',0
msg1 db 'Nice',0
msg3 db 'bad',0
pe32 PROCESSENTRY32 ?

section '.code' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
invoke DisableThreadLibraryCalls,[hinstDLL]
invoke CreateToolhelp32Snapshot,8,0
mov [Handle],eax
mov eax,sizeof.PROCESSENTRY32
mov [pe32.dwSize], eax
invoke Thread32First,[Handle],pe32 ; - здесь проблемка
cmp eax,0 ; проверка результата
jz .Figovo
mov eax,1
ret
.Figovo:
invoke MessageBoxA,0,msg3,msg3,MB_OK
mov eax,1
ret
endp
MSDN CreateToolhelp32Snapshot (http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682489%28v=vs.85%29.aspx)
Попутно смотрел
1) Руткит (http://forum.k0d.cc/showthread.php?t=6907)
2) Аналог то, что я щас пишу (http://forum.gamehacklab.ru/topic/1111-%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0-%D1%81-fasm/)
Кто сталкивался с проблемкой?

n1ghtmare
08.02.2013, 21:45
Если не секрет, откуда столько любви к ассемблеру? Чем языки более высокого уровня не угодили?
Вот код не моего фреймворка для инжекта длл перенаправлением потока, код на C# но зная хоть примерно C++ можно понять. ManagedFasm это обертка над компилятором твоего любимого)
/// <summary>
/// Injects a dll into a process by hijacking the given thread and redirecting it to LoadLibrary.
/// </summary>
/// <param name="hProcess">Handle to process into which dll will be injected.</param>
/// <param name="hThread">Handle to thread that will be hijacked.</param>
/// <param name="szDllPath">Full path to the dll to be injected.</param>
/// <returns>Returns the base address of the injected dll on success, zero on failure.</returns>
public static uint InjectDllRedirectThread(IntPtr hProcess, IntPtr hThread, string szDllPath)
{
const uint INITIAL_EXIT_CODE = 0xFFFFFFFF;

if (hProcess == IntPtr.Zero)
throw new ArgumentNullException("hProcess");

if (hThread == IntPtr.Zero)
throw new ArgumentNullException("hThread");

if (szDllPath.Length == 0)
throw new ArgumentNullException("szDllPath");

if (!szDllPath.Contains("\\"))
szDllPath = System.IO.Path.GetFullPath(szDllPath);

if (!System.IO.File.Exists(szDllPath))
throw new ArgumentException("DLL not found.", "szDllPath");

uint dwBaseAddress = RETURN_ERROR;
uint lpLoadLibrary, lpAsmStub;
CONTEXT ctx;
StringBuilder AssemblyStub = new StringBuilder();
ManagedFasm fasm = new ManagedFasm(hProcess);

lpLoadLibrary = (uint)Imports.GetProcAddress(Imports.GetModuleHand le("kernel32.dll"), "LoadLibraryA");
if (lpLoadLibrary == 0)
return RETURN_ERROR;

lpAsmStub = SMemory.AllocateMemory(hProcess);
if (lpAsmStub == 0)
return RETURN_ERROR;

if (SThread.SuspendThread(hThread) != uint.MaxValue)
{
ctx = SThread.GetThreadContext(hThread, CONTEXT_FLAGS.CONTEXT_CONTROL);
if (ctx.Eip > 0)
{
try
{
//located at lpAsmStub+0, where we can monitor LoadLibrary's exit code.
fasm.AddLine("lpExitCode dd 0x{0:X}", INITIAL_EXIT_CODE);

//lpAsmStub+4, where the actual code part starts
fasm.AddLine("push 0x{0:X}", ctx.Eip);
fasm.AddLine("pushad");
fasm.AddLine("push szDllPath");
fasm.AddLine("call 0x{0:X}", lpLoadLibrary);
fasm.AddLine("mov [lpExitCode], eax");
fasm.AddLine("popad");
fasm.AddLine("retn");

//dll path
fasm.AddLine("szDllPath db \'{0}\',0", szDllPath);

fasm.Inject(lpAsmStub);
}
catch
{
SMemory.FreeMemory(hProcess, lpAsmStub);
SThread.ResumeThread(hThread);
return RETURN_ERROR;
}

ctx.ContextFlags = CONTEXT_FLAGS.CONTEXT_CONTROL;
ctx.Eip = lpAsmStub + 4; //skip over lpExitCode data

if (SThread.SetThreadContext(hThread, ctx))
{
if (SThread.ResumeThread(hThread) != uint.MaxValue)
{
for (int i = 0; i < 400; i++)
{
System.Threading.Thread.Sleep(5);
if ((dwBaseAddress = SMemory.ReadUInt(hProcess, lpAsmStub)) != INITIAL_EXIT_CODE)
break;
}
}
}
}
}

if (fasm != null)
{
fasm.Dispose();
fasm = null;
}

SMemory.FreeMemory(hProcess, lpAsmStub);

return dwBaseAddress;
}

St1mul
08.02.2013, 22:33
Если не секрет, откуда столько любви к ассемблеру? Чем языки более высокого уровня не угодили?
Начинал вообще с ольки, потом как то ни один язык так не прижился как фасм, масм слишком много писать, остальные языки слишком простые чтобы начинать, да и начал все это чтобы научится делать такую штуку как сделал GoldFinch

Добавлено через 18 минут
Спасибо Demion'у за помощь
Я не ту структуру записывал, нужно было
struct THREADENTRY32
dwSize dd ?
cntUsage dd ?
th32ThreadID dd ?
th32OwnerProcessID dd ?
tpBasePri dd ?
tpDeltaPri dd ?
dwFlags dd ?
ends
а я вместо неё засовывал структуру PROCESSENTRY32
+ еще поменять invoke CreateToolhelp32Snapshot,4,0
Дальше делаем мини цикл по отсеиванию ненужных потоков и готово!

Sherman
08.02.2013, 23:41
Если не секрет, откуда столько любви к ассемблеру? Чем языки более высокого уровня не угодили?
Вот код не моего фреймворка для инжекта длл перенаправлением потока, код на C# но зная хоть примерно C++ можно понять. ManagedFasm это обертка над компилятором твоего любимого)


Сегодня днем я спрашивал его о том же...

St1mul, если бы ты внимательно смотрел пример с MSDN (http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686701(v=vs.85).aspx), в особенности начало ф-ции ListProcessThreads, то победил бы свою проблему гораздо раньше )

CreateToolhelp32Snapshot,4,0

Для твоей задачи надо передавать Pid процесса ( GetCurrentProcessId() ) в котором ты находишься, и не надо будет отсеивать чужие потоки.

St1mul
10.02.2013, 09:44
Стал дальше копать.
Как открыть поток на полных правах?
MSDN OpenThread (http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684335%28v=vs.85%29.aspx)
Thread access (http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686769%28v=vs.85%29.aspx)
я вижу там есть THREAD_ALL_ACCESS, мне его и нужно, но там нету значения, а в фасме нет такой константы (это же фасм), со стандарт правами открывать не вариант т.к. эти все права нужны для SetThreadContext
Список имеющихся констант
; Access rights

DELETE_RIGHT = 00010000h
READ_CONTROL = 00020000h
WRITE_DAC = 00040000h
WRITE_OWNER = 00080000h
SYNCHRONIZE = 00100000h
STANDARD_RIGHTS_READ = READ_CONTROL
STANDARD_RIGHTS_WRITE = READ_CONTROL
STANDARD_RIGHTS_EXECUTE = READ_CONTROL
STANDARD_RIGHTS_REQUIRED = 000F0000h
STANDARD_RIGHTS_ALL = 001F0000h
SPECIFIC_RIGHTS_ALL = 0000FFFFh
ACCESS_SYSTEM_SECURITY = 01000000h
MAXIMUM_ALLOWED = 02000000h
GENERIC_READ = 80000000h
GENERIC_WRITE = 40000000h
GENERIC_EXECUTE = 20000000h
GENERIC_ALL = 10000000h
PROCESS_TERMINATE = 00000001h
PROCESS_CREATE_THREAD = 00000002h
PROCESS_VM_OPERATION = 00000008h
PROCESS_VM_READ = 00000010h
PROCESS_VM_WRITE = 00000020h
PROCESS_DUP_HANDLE = 00000040h
PROCESS_CREATE_PROCESS = 00000080h
PROCESS_SET_QUOTA = 00000100h
PROCESS_SET_INFORMATION = 00000200h
PROCESS_QUERY_INFORMATION = 00000400h
PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or 0FFFh
FILE_SHARE_READ = 00000001h
FILE_SHARE_WRITE = 00000002h
FILE_SHARE_DELETE = 00000004h
Кто может подсказать?)
Может кто сделать мини прогу на дельфи с функцией открытия потока на полных правах и скинуть ее сюда?

Sherman
10.02.2013, 10:57
Яркий пример поговорки - "Смотрю в книгу, вижу фигу".

Почитать про OR и прочие логические операции (http://ru.wikipedia.org/wiki/%D0%9B%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D 0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0 %B8%D1%8F)

Как прочтешь, сложи три значения.

PROCESS_ALL_ACCESS = 000F0000h or 00100000h or 0FFFh

St1mul
11.02.2013, 23:05
Яркий пример поговорки - "Смотрю в книгу, вижу фигу".

Почитать про OR и прочие логические операции

Как прочтешь, сложи три значения.

PROCESS_ALL_ACCESS = 000F0000h or 00100000h or 0FFFh
все равно при вызове SetThreadContext пишет в логе ошибок no access
P.S. есть у кого материалы по обходу чек суммы приложения?

Sherman
11.02.2013, 23:33
Там анализировать способ контроля надо.

St1mul
04.03.2013, 06:25
Понадобилось перейти с win32 на win7.
Но при отладке кода в ольке завистает на моем коде в функции создания l2parameterstack, хотя в win32 все прекрасно работало
Вот чать кода:
Buffer1 db 16 dup(0) ; массив 16 байтовый
.........
lea ecx,[Buffer1]
invoke Stack_Create,ecx,10
.........
Stack_Create,'??0L2ParamStack@@QAE@H@Z'
Кто знает в чем проблема, кто сталкивался?