穿越wow64到native64

// just test on win7sp1x64
#include <windows.h>
#include <stdlib.h>
  
typedef enum _MEMORY_INFORMATION_CLASS {
    MemoryBasicInformation,
    MemoryWorkingSetList,
    MemorySectionName,
    MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;

LONG (WINAPI 
*pfn_NtQueryVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN PVOID BaseAddress,
    IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
    OUT PVOID MemoryInformation,
    IN SIZE_T MemoryInformationLength,
    OUT PSIZE_T ReturnLength
    );
    
typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

WCHAR gModuleName[] = L"C:\\windows\\system32\\kernelbase.dll";
WCHAR gNtdllPath[]  = L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll";

PVOID __fastcall GetFuncAddress64(PVOID ImageBase, PUCHAR ApiName )
{
    PVOID   FuncAddress = NULL;
    
    PIMAGE_DOS_HEADER       DosHdr ;
    PIMAGE_NT_HEADERS32     NtHdrs ;
    PIMAGE_NT_HEADERS64     NtHdrs2;
    PIMAGE_DATA_DIRECTORY   DatDir ;
    PIMAGE_EXPORT_DIRECTORY ExpDir ;
    PULONG          AddressOfNames ;
    PULONG      AddressOfFunctions ;
    PUSHORT  AddressOfNameOrdinals ;    
    BOOL    bAMD64 = FALSE;
    LONG    Idx;
    LONG    ret;
    LONG    low;
    LONG    mid;
    LONG    high;
    PCHAR   pName;
    
    do
    {
        (PVOID)DosHdr  = ImageBase;
        if( !DosHdr || DosHdr->e_magic != IMAGE_DOS_SIGNATURE )
        {
            break;
        }
        
        (PUCHAR)NtHdrs = (PUCHAR)ImageBase + DosHdr->e_lfanew;   
        if( (PUCHAR)NtHdrs <(PUCHAR)DosHdr || NtHdrs->Signature != IMAGE_NT_SIGNATURE )
        {
            break;
        }        
        
        (PUCHAR)NtHdrs2 = (PUCHAR)NtHdrs;        
        if( NtHdrs->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && NtHdrs2->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC )
        {
            break;
        }
        
        bAMD64 = NtHdrs2->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;        
        if( bAMD64 )
        {                        
            DatDir = &NtHdrs2->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
        }
        else
        {   
            DatDir = &NtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
        }    
        
        if( DatDir->Size == 0 || DatDir->VirtualAddress == 0 )
        {
            break;
        }
        
        (PUCHAR)ExpDir = (PUCHAR)ImageBase + DatDir->VirtualAddress;
        if ( (PUCHAR)ExpDir < (PUCHAR)NtHdrs )
        {
            break;
        }
        
        AddressOfNames          = (PULONG)( (ULONG)ImageBase + ExpDir->AddressOfNames );
        AddressOfFunctions      = (PULONG)( (ULONG)ImageBase + ExpDir->AddressOfFunctions );
        AddressOfNameOrdinals   = (PUSHORT)( (ULONG)ImageBase + ExpDir->AddressOfNameOrdinals );

        high = ExpDir->NumberOfNames-1;
        low  = 0;
        while(low <= high)//二分查找,快速定位
        {
            mid   = (high+low)>>1;
            pName = (PCHAR)ImageBase+AddressOfNames[mid] ;

            Idx = 0;
            while( pName[Idx] && pName[Idx] == ApiName[Idx] )
            {
                ++Idx;
            }

            ret = pName[Idx] - ApiName[Idx];
            if ( ret==0 )
            {
                (PUCHAR)FuncAddress=(PUCHAR)ImageBase + AddressOfFunctions[ AddressOfNameOrdinals[ mid ] ];
                break;
            }
            else if( ret > 0 )
            {
                high=mid-1;
            }
            else
            {
                low=mid+1;
            }
        } 
        
    }while( FALSE );

    return FuncAddress;
}

PVOID WINAPI GetNativeNtdll( )
{
    PVOID  hNtdll = NULL;
    PUCHAR ptr = (PUCHAR)GetModuleHandleA( NULL ) + 0x100000;
    MEMORY_BASIC_INFORMATION MemInfo;
    SIZE_T RetLen;
    LONG   Status;
    WCHAR   NameBuf[MAX_PATH+16];    
    HANDLE hProcess = GetCurrentProcess();
    PUNICODE_STRING Filename = (PUNICODE_STRING)NameBuf;
    
    if( !pfn_NtQueryVirtualMemory )
    {
        (FARPROC)pfn_NtQueryVirtualMemory = GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtQueryVirtualMemory" );
    }
    
    if( !pfn_NtQueryVirtualMemory )
    {
        return hNtdll;
    }
    
    while( ptr < (PUCHAR)0x80000000 )
    {
        Status = pfn_NtQueryVirtualMemory( hProcess, ptr, MemoryBasicInformation, &MemInfo, sizeof(MemInfo), &RetLen);        
        if( Status < 0 )
        {
            ptr += 0x10000;
            continue;
        }
         
        if( MemInfo.State == MEM_COMMIT && MEM_IMAGE == MemInfo.Type )
        {
            Status = pfn_NtQueryVirtualMemory( hProcess, ptr, MemorySectionName, Filename, sizeof(NameBuf), &RetLen );
            if( Status == 0 )
            {   
                if( !_wcsnicmp(gNtdllPath, Filename->Buffer, Filename->Length) )
                {
                    hNtdll = (PVOID)ptr;
                    break;
                }
            }             
        }
        
        ptr += MemInfo.RegionSize;
    }
    
    return hNtdll;
}

PVOID WINAPI MapDllToMem( PCWSTR FileName )
{
    PVOID  DllBase = NULL;
    HANDLE hFile;
    CHAR   DllData[512];
    DWORD  dwRetLen;
    BOOL   bRet;
    ULONG  SizeOfImage;
    ULONG  SizeOfHeaders;
    ULONG  NumOfSections;
    ULONG  Index;
    
    PIMAGE_DOS_HEADER DosHdr ;
    PIMAGE_NT_HEADERS NtHdrs ;
    PIMAGE_SECTION_HEADER SecHdr;

    BOOL    bAMD64 = FALSE;
    
    do
    {
        hFile = CreateFileW( FileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
        if( hFile ==  INVALID_HANDLE_VALUE ) break;
        
        bRet = ReadFile( hFile, DllData, sizeof(DllData), &dwRetLen, NULL );
        if( !bRet ) break;
        
        DosHdr = (PIMAGE_DOS_HEADER)DllData;
        if( !DosHdr || DosHdr->e_magic != IMAGE_DOS_SIGNATURE )
        {
            break;
        }
        
        (PUCHAR)NtHdrs = (PUCHAR)DllData + DosHdr->e_lfanew;   
        if( (PUCHAR)NtHdrs <(PUCHAR)DosHdr || NtHdrs->Signature != IMAGE_NT_SIGNATURE )
        {
            break;
        }
                
        NumOfSections = NtHdrs->FileHeader.NumberOfSections;
        SizeOfHeaders = NtHdrs->OptionalHeader.SizeOfHeaders;
        SizeOfImage   = NtHdrs->OptionalHeader.SizeOfImage;        
        
        DllBase = VirtualAlloc( NULL, SizeOfImage, MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
        if( !DllBase )break;
        
        RtlZeroMemory( DllBase, SizeOfImage );
        SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
        ReadFile( hFile, DllBase, SizeOfHeaders, &dwRetLen, NULL );
        
        (PUCHAR)SecHdr = (PUCHAR)DllBase + ((PUCHAR)&NtHdrs->OptionalHeader - DllData) + NtHdrs->FileHeader.SizeOfOptionalHeader ;
        for( Index=0; Index<NumOfSections; Index++ )
        {
            SetFilePointer( hFile, SecHdr->PointerToRawData, NULL, FILE_BEGIN );
            ReadFile( hFile, (PUCHAR)DllBase + SecHdr->VirtualAddress, SecHdr->SizeOfRawData, &dwRetLen, NULL );
            
            SecHdr++;
        }
        
    }while( FALSE );    
    
    return DllBase;
}

VOID WINAPI UnMapDllFromMem( PVOID DllBase )
{
    VirtualFree( DllBase, 0, MEM_RELEASE );
}

BOOL WINAPI Wow64Check()
{
    BOOL    bWow64 = FALSE;    
    return IsWow64Process(GetCurrentProcess(), &bWow64) && bWow64;
}

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{   
    HMODULE hNtdll32 = GetModuleHandleA("ntdll.dll");
    HMODULE hNtdll = (HMODULE)GetNativeNtdll( );
    
    if( hNtdll32 && hNtdll && Wow64Check() )
    {
        PVOID   OldValue;
        PVOID   MemNtdllx64;
        BOOL    bProtectChanged;
        ULONG   OldProtect;
        PUCHAR  Buf = VirtualAlloc( NULL, 4096, MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);    
        if( Buf )
        {        
            LONG (WINAPI* pfn_NtDeleteKey)( HANDLE );
            PUCHAR pData = Buf+256;
            PUCHAR pInst = Buf+256+256; 
            
            RtlFillMemory( Buf,   256, 0 );
            RtlFillMemory( pData, 256, 0 );
            RtlFillMemory( pInst, 256, 0xCC );
            
            *(PULONG)(Buf+0) = 0x00460044;        
            *(PULONG)(Buf+8) = (ULONG)Buf + 0x10;
            RtlMoveMemory( Buf + 16 , gModuleName, 34*sizeof(WCHAR) );
            
            *(PULONG)(pInst+ 0) = 0x40EC8148;    //sub rsp, 40;
            *(PULONG)(pInst+ 4) = 0x90000000;
            *(PULONG)(pInst+ 8) = 0x90C93348;    //xor rcx,rcx
            *(PULONG)(pInst+12) = 0x90D23348;    //xor rdx,rdx
            *(PULONG)(pInst+16) = 0xF9000068;    //push, dllpath 
            *(PULONG)(pInst+20) = 0x9058417E;    //pop r8
            *(PULONG)(pInst+17) = (ULONG)Buf;            
            *(PULONG)(pInst+24) = 0xF9000068;    //push, pData
            *(PULONG)(pInst+28) = 0x9059417E;    //pop r9
            *(PULONG)(pInst+25) = (ULONG)pData;             
            *(PULONG)(pInst+32) = 0x017AC068;    //push offset ntdll!LdrLoadDll 
            *(PULONG)(pInst+36) = 0xD0FF5877;    //pop  rax; call rax
            /*  00000000`7ef90228 680001f97e      push    7EF90100h
                00000000`7ef9022d 5e              pop     rsi
                00000000`7ef9022e 8b06            mov     eax,dword ptr [rsi]
                00000000`7ef90230 014610          add     dword ptr [rsi+10h],eax
                00000000`7ef90233 014618          add     dword ptr [rsi+18h],eax
                00000000`7ef90236 014620          add     dword ptr [rsi+20h],eax
                00000000`7ef90239 4833c9          xor     rcx,rcx
                00000000`7ef9023c 681000f97e      push    7EF90010h
                00000000`7ef90241 5a              pop     rdx
                00000000`7ef90242 ff5620          call    qword ptr [rsi+20h]
                00000000`7ef90245 83c440          add     esp,40h
                00000000`7ef90248 c3              ret     */       
            *(PULONG)(pInst+40) = 0xf9010068;
            *(PULONG)(pInst+44) = 0x068b5e7e;
            *(PULONG)(pInst+48) = 0x01104601;
            *(PULONG)(pInst+52) = 0x46011846;
            *(PULONG)(pInst+56) = 0xc9334820;
            *(PULONG)(pInst+60) = 0xf9001068;
            *(PULONG)(pInst+64) = 0x56ff5a7e; 
            *(PULONG)(pInst+68) = 0x40c48320;
            *(PSHORT)(pInst+72) = 0xCCC3;             
            *(PULONG)(pInst+41) = (ULONG)pData;
            *(PULONG)(pInst+61) = (ULONG)Buf+16;
              
            *(PVOID*)(pInst+33) = GetFuncAddress64( (PVOID)hNtdll, "LdrLoadDll" );
            (PVOID)pfn_NtDeleteKey  = GetFuncAddress64( (PVOID)hNtdll, "NtDeleteKey" );
            
            Wow64DisableWow64FsRedirection(&OldValue);
            MemNtdllx64 = MapDllToMem( gModuleName ); 
            Wow64RevertWow64FsRedirection(OldValue);
            
            if( MemNtdllx64 )
            {
                *(PULONG)(pData + 0x10) = (ULONG)GetFuncAddress64( (PVOID)MemNtdllx64, "GetProcAddress" ) - (ULONG)MemNtdllx64;
                *(PULONG)(pData + 0x18) = (ULONG)GetFuncAddress64( (PVOID)MemNtdllx64, "OpenProcess" ) - (ULONG)MemNtdllx64;
                *(PULONG)(pData + 0x20) = (ULONG)GetFuncAddress64( (PVOID)MemNtdllx64, "FatalAppExitW" ) - (ULONG)MemNtdllx64;
                UnMapDllFromMem( MemNtdllx64 );  
            }

            bProtectChanged = VirtualProtect( (PVOID)pfn_NtDeleteKey, 0x20, PAGE_EXECUTE_READWRITE, &OldProtect );
            if( bProtectChanged )
            {
                *(PUSHORT)pfn_NtDeleteKey = 0xB848;
                *(PULONG)((PUCHAR)pfn_NtDeleteKey + 2) = (ULONG)pInst;
                *(PULONG)((PUCHAR)pfn_NtDeleteKey + 6) = 0x00;
                *(PULONG)((PUCHAR)pfn_NtDeleteKey + 10)= 0xCCCCE0FF;
                VirtualProtect( (PVOID)pfn_NtDeleteKey, 0x20, OldProtect, &OldProtect );
                
                (PVOID)pfn_NtDeleteKey  = GetFuncAddress64( (PVOID)hNtdll32, "NtDeleteKey" );
                pfn_NtDeleteKey( (HANDLE)pInst );
            }
            
            VirtualFree( Buf, 0, MEM_RELEASE );
        }
    }
    
    return 0;
}


转载于:https://my.oschina.net/ejoyc/blog/198363

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值