PDA

Просмотр полной версии : [Статья] Сканер сигнатур для Delphi by ArxLex


arxlex
26.05.2014, 07:52
Привет всем! Решил поделиться сканером сигнатур написанный мною aka ArxLex на Delphi. Материал чисто для ознакомительных целей. В качестве основы и принципа работы были взяты функции с C++. Пример написан для новичков и любителей WINAPI в виде консольного приложения, для большего удобства и понимания кода.

program signaturescanner;
{$APPTYPE CONSOLE}

uses
Windows, SysUtils, TlHelp32;

var
m_pID: integer;
m_hProc: THandle;
module: TModuleEntry32;
m_Sign: integer;

const
procName = 'D3D9Test.exe';

procedure GetPID;
var
snapshot: THandle;
pInfo: PROCESSENTRY32;
begin
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pInfo.dwSize := sizeof(PROCESSENTRY32);
if (Process32First(snapshot, pInfo)) then
begin
while (Process32Next(snapshot, pInfo)) do
begin
if pInfo.szExeFile = procName then
begin
m_pID := pInfo.th32ProcessID;
CloseHandle(snapshot);
exit;
end;
end;
end;
m_pID := 0;
CloseHandle(snapshot);
exit;
end;

function GetModuleInfo(const module_name: PChar; main_process: boolean): TModuleEntry32;
var
snapshot: THandle;
module: TModuleEntry32;
begin
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_pID);
module.dwSize := sizeof(TModuleEntry32);
if (Module32First(snapshot, module)) then
begin
if (main_process) then
begin
CloseHandle(snapshot);
result := module;
end;
while (Module32Next(snapshot, module)) do
begin
if (StrIComp(PChar(ExtractFileName(module.szModule)), PChar(module_name)) = 0) then
begin
CloseHandle(snapshot);
result := module;
end;
end;
end;
result := module;
end;

function DataCompare(data: PByte; sign: PByte; mask: PAnsiChar): boolean;
begin
while mask^ <> #0 do
begin
if ((mask^ = 'x') and (data^ <> sign^)) then
begin
result := false;
exit;
end;
inc(mask);
inc(data);
inc(sign);
end;
result := true;
end;

function ScanSignature(base: Dword; size: Dword; sign: PByte; mask: PAnsiChar): integer;
var
mbi: MEMORY_BASIC_INFORMATION;
offset: integer;
buffer: PByte;
BytesRead: Dword;
i: integer;
begin
offset := 0;
while (offset < size) do
begin
VirtualQueryEx(m_hProc, Pointer(base + offset), &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (mbi.State <> MEM_FREE) then
begin
GetMem(buffer, mbi.RegionSize);
ReadProcessMemory(m_hProc, mbi.BaseAddress, buffer, mbi.RegionSize, BytesRead);
for i := 0 to mbi.RegionSize do
begin
if (DataCompare(buffer + i, sign, mask)) then
begin
FreeMem(buffer);
result := integer(mbi.BaseAddress) + i;
exit;
end;
end;
FreeMem(buffer);
end;
offset := offset + mbi.RegionSize;
end;
result := 0;
end;

const
Sign: array [0 .. 22] of byte = ($68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $FF, $15, $00, $00, $00, $00, $6A, $20);
Mask = 'x????x????x????xx????xx';

begin
GetPID();
if (m_pID <> 0) then
begin
module := GetModuleInfo(nil, true);
m_hProc := OpenProcess(PROCESS_ALL_ACCESS, false, m_pID);
m_Sign := ScanSignature(integer(module.modBaseAddr), module.modBaseSize, @Sign, Mask);
writeln(' ************************************************** ***********');
writeln(' * Signature Scanner for Delphi *');
writeln(' * Special for Cheat[ON].ru by ArxLex *');
writeln(' ************************************************** ***********'+#10#13#10#13);
writeln(' Handle Process: $', inttohex(m_hProc, sizeof(m_hProc)));
writeln(' Pid: $', inttohex(m_pID, sizeof(m_pID)));
writeln(' Process Base Address: $', inttohex(integer(module.modBaseAddr), sizeof(module.modBaseAddr)));
writeln(' Process Base Size: $', inttohex(module.modBaseSize, sizeof(module.modBaseSize)));
writeln(' Signature Address: $', inttohex(m_Sign, sizeof(m_Sign)));
readln;
CloseHandle(m_hProc);
end;

end.

Источник: cheaton.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

Dinmaite[Work]
26.05.2014, 13:33
где?

...
ну вот, другое дело

артём612
26.05.2014, 17:13
;5394847']где?
Он просто сделал чтобы код открывался после того как ему поставят спасибо
Но [THANKLIM] походу работает криво

вот что должно быть



program signaturescanner;
{$APPTYPE CONSOLE}

uses
Windows, SysUtils, TlHelp32;

var
m_pID: integer;
m_hProc: THandle;
module: TModuleEntry32;
m_Sign: integer;

const
procName = 'D3D9Test.exe';

procedure GetPID;
var
snapshot: THandle;
pInfo: PROCESSENTRY32;
begin
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pInfo.dwSize := sizeof(PROCESSENTRY32);
if (Process32First(snapshot, pInfo)) then
begin
while (Process32Next(snapshot, pInfo)) do
begin
if pInfo.szExeFile = procName then
begin
m_pID := pInfo.th32ProcessID;
CloseHandle(snapshot);
exit;
end;
end;
end;
m_pID := 0;
CloseHandle(snapshot);
exit;
end;

function GetModuleInfo(const module_name: PChar; main_process: boolean): TModuleEntry32;
var
snapshot: THandle;
module: TModuleEntry32;
begin
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_pID);
module.dwSize := sizeof(TModuleEntry32);
if (Module32First(snapshot, module)) then
begin
if (main_process) then
begin
CloseHandle(snapshot);
result := module;
end;
while (Module32Next(snapshot, module)) do
begin
if (StrIComp(PChar(ExtractFileName(module.szModule)), PChar(module_name)) = 0) then
begin
CloseHandle(snapshot);
result := module;
end;
end;
end;
result := module;
end;

function DataCompare(data: PByte; sign: PByte; mask: PAnsiChar): boolean;
begin
while mask^ <> #0 do
begin
if ((mask^ = 'x') and (data^ <> sign^)) then
begin
result := false;
exit;
end;
inc(mask);
inc(data);
inc(sign);
end;
result := true;
end;

function ScanSignature(base: Dword; size: Dword; sign: PByte; mask: PAnsiChar): integer;
var
mbi: MEMORY_BASIC_INFORMATION;
offset: integer;
buffer: PByte;
BytesRead: Dword;
i: integer;
begin
offset := 0;
while (offset < size) do
begin
VirtualQueryEx(m_hProc, Pointer(base + offset), &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (mbi.State <> MEM_FREE) then
begin
GetMem(buffer, mbi.RegionSize);
ReadProcessMemory(m_hProc, mbi.BaseAddress, buffer, mbi.RegionSize, BytesRead);
for i := 0 to mbi.RegionSize do
begin
if (DataCompare(buffer + i, sign, mask)) then
begin
FreeMem(buffer);
result := integer(mbi.BaseAddress) + i;
exit;
end;
end;
FreeMem(buffer);
end;
offset := offset + mbi.RegionSize;
end;
result := 0;
end;

const
Sign: array [0 .. 22] of byte = ($68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $FF, $15, $00, $00, $00, $00, $6A, $20);
Mask = 'x????x????x????xx????xx';

begin
GetPID();
if (m_pID <> 0) then
begin
module := GetModuleInfo(nil, true);
m_hProc := OpenProcess(PROCESS_ALL_ACCESS, false, m_pID);
m_Sign := ScanSignature(integer(module.modBaseAddr), module.modBaseSize, @Sign, Mask);
writeln(' ************************************************** ***********');
writeln(' * Signature Scanner for Delphi *');
writeln(' * Special for Cheat[ON].ru by ArxLex *');
writeln(' ************************************************** ***********'+#10#13#10#13);
writeln(' Handle Process: $', inttohex(m_hProc, sizeof(m_hProc)));
writeln(' Pid: $', inttohex(m_pID, sizeof(m_pID)));
writeln(' Process Base Address: $', inttohex(integer(module.modBaseAddr), sizeof(module.modBaseAddr)));
writeln(' Process Base Size: $', inttohex(module.modBaseSize, sizeof(module.modBaseSize)));
writeln(' Signature Address: $', inttohex(m_Sign, sizeof(m_Sign)));
readln;
CloseHandle(m_hProc);
end;

end.

Источник: cheaton.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
(C)arxlex

Тигрь
28.05.2014, 18:19
Ужасная реализация, всегда ужасался когда натыкался на исходники читов для PB на с++ и там был этот сканер сигнатур. Зачем делать сигнатуру и маску? Когда это все можно записать в одной строке.
Вот в соседней теме нормальная реализация сигнатурного поиска, за исключением того как в функцию передаются параметры(если бы это было не в виде длл то было бы нормально), ну и еще на кой-то адрес возвращается как строка.
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

N0iD
22.06.2014, 04:41
Приветствую, возможно мой вопрос будет нубским, но все же прошу обратить на него внимание.

При попытке компиляции ругается на выделенное красным: &mbi скорей всего опечатка, но все же.

function ScanSignature(base: Dword; size: Dword; sign: PByte; mask: PAnsiChar): integer;
var
mbi: MEMORY_BASIC_INFORMATION;
offset: integer;
buffer: PByte;
BytesRead: Dword;
i: integer;
begin
offset := 0;
while (offset < size) do
begin
VirtualQueryEx(m_hProc, Pointer(base + offset), &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (mbi.State <> MEM_FREE) then
begin
GetMem(buffer, mbi.RegionSize);
ReadProcessMemory(m_hProc, mbi.BaseAddress, buffer, mbi.RegionSize, BytesRead);
for i := 0 to mbi.RegionSize do
begin
if (DataCompare(buffer + i, sign, mask)) then
begin
FreeMem(buffer);
result := integer(mbi.BaseAddress) + i;
exit;
end;
end;
FreeMem(buffer);
end;
offset := offset + mbi.RegionSize;
end;
result := 0;
end;


И каким образом подбирается данное значение, собственно то которое выделено красным.


Sign: array [0 .. 22] of byte = ($68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $FF, $15, $00, $00, $00, $00, $6A, $20);
Mask = 'x????x????x????xx????xx';

VeTaL_UA
12.08.2014, 10:41
Sign: array [0 .. 22] of byte = ($68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $68, $00, $00, $00, $00, $FF, $15, $00, $00, $00, $00, $6A, $20);
Ну очевидно же, что по количеству элементов массива, в массиве 23 байта, значит от 0 до 22 индексы идут.