Ejemplo n.º 1
0
ULONG GetThreadFlagsOffset()
{
	UCHAR *cPtr, *pOpcode;
	ULONG Length;
	USHORT Offset;

	for (cPtr = (PUCHAR)PsTerminateSystemThread;
		cPtr < (PUCHAR)PsTerminateSystemThread + 0x100;
		cPtr += Length)
	{
		Length = SizeOfCode(cPtr, &pOpcode);
		if (!Length) break;
		if (*(USHORT *)pOpcode == 0x80F6)
		{
			Offset = *(USHORT *)((ULONG)pOpcode + 2);
			return Offset;
		}
	}
	return 0;
}
Ejemplo n.º 2
0
LPVOID CreateBridge(LPVOID lpFunc,LPVOID lpBackup,SIZE_T *dwBackupCodeSize,ULONG_PTR *lpTable)
{
    LPVOID lpBridge=MemAlloc(JUMP_SIZE*6);
    if (lpBridge)
    {
        DWORD dwOldProtect=0;
        VirtualProtect(lpBridge,JUMP_SIZE*6,PAGE_EXECUTE_READWRITE,&dwOldProtect);
#ifdef _AMD64_
        CALL_ABS call={0x15FF,0x00000000};
        JMP_ABS jmp={0x25FF,0x00000000};
        JCC_ABS jcc={0x70,0x02,0xEB,0x06,0x25FF,0x00000000};
        int dwTmpAddrsCount=0;
#else
        CALL_REL call={0xE8,0x00000000};
        JMP_REL jmp={0xE9,0x00000000};
        JCC_REL jcc={0x800F,0x00000000};
#endif
        TEMP_ADDR TmpAddr[MAX_JUMPS]={0};
        int dwTmpAddrCount=0;

		SIZE_T dwOldPos=0,dwNewPos=0;
		ULONG_PTR dwJmpDest=0;
		bool bDone=false;
        while (!bDone)
		{
		    hdes hs;
			LPVOID lpInst=(LPVOID)((ULONG_PTR)lpFunc+dwOldPos);
		    SIZE_T dwCopySize=SizeOfCode(lpInst);
            if ((hs.flags & F_ERROR) == F_ERROR)
                break;

            LPVOID lpCopySrc=lpInst;
            if ((ULONG_PTR)lpInst-(ULONG_PTR)lpFunc >= sizeof(JMP_REL))
            {
                LPVOID lpTmpAddr=0;
#ifdef _AMD64_
                lpTmpAddr=&lpTable[dwTmpAddrsCount++];
                if (dwTmpAddrsCount > MAX_JUMPS)
                    break;
#endif
                AppendTempAddress(lpInst,dwNewPos,&jmp,&TmpAddr[dwTmpAddrCount++],(void **)lpTmpAddr);
                if (dwTmpAddrCount > MAX_JUMPS)
                    break;

                lpCopySrc=&jmp;
                dwCopySize=sizeof(jmp);

                bDone=true;
            }
#ifdef _AMD64_
			else if ((hs.modrm & 0xC7) == 0x05) // RIP-based
			{
				AppendRipRelativeAddress(lpInst,dwNewPos,&hs,&TmpAddr[dwTmpAddrCount++]);
                if (dwTmpAddrCount > MAX_JUMPS)
                    break;

				if ((hs.opcode == 0xFF) && (hs.modrm_reg == 4)) // jmp
					bDone=true;
			}
#endif
			else if (hs.opcode == 0xE8) // call
			{
                LPVOID lpTmpAddr=0;
#ifdef _AMD64_
                lpTmpAddr=&lpTable[dwTmpAddrsCount++];
                if (dwTmpAddrsCount > MAX_JUMPS)
                    break;
#endif
				AppendTempAddress(GetRelativeBranchDestination(lpInst,&hs),dwNewPos,&call,&TmpAddr[dwTmpAddrCount++],(void **)lpTmpAddr);
                if (dwTmpAddrCount > MAX_JUMPS)
                    break;

				lpCopySrc=&call;
				dwCopySize=sizeof(call);
			}
			else if ((hs.opcode & 0xFD) == 0xE9) // jmp
			{
				LPVOID lpDest=GetRelativeBranchDestination(lpInst,&hs);

				if (IsInternalJump(lpFunc,(ULONG_PTR)lpDest))
					dwJmpDest=max(dwJmpDest,(ULONG_PTR)lpDest);
				else
				{
                    LPVOID lpTmpAddr=0;
#ifdef _AMD64_
                    lpTmpAddr=&lpTable[dwTmpAddrsCount++];
                    if (dwTmpAddrsCount > MAX_JUMPS)
                        break;
#endif
					AppendTempAddress(lpDest,dwNewPos,&jmp,&TmpAddr[dwTmpAddrCount++],(void **)lpTmpAddr);
                    if (dwTmpAddrCount > MAX_JUMPS)
                        break;

					lpCopySrc = &jmp;
					dwCopySize = sizeof(jmp);

					bDone=((ULONG_PTR)lpInst >= dwJmpDest);
				}
			}
			else if (((hs.opcode & 0xF0) == 0x70) || (hs.opcode == 0xE3) || ((hs.opcode2 & 0xF0) == 0x80)) // jcc
			{
			    LPVOID lpDest=GetRelativeBranchDestination(lpInst,&hs);

				if (IsInternalJump(lpFunc,(ULONG_PTR)lpDest))
					dwJmpDest=max(dwJmpDest,(ULONG_PTR)lpDest);
				else if (hs.opcode == 0xE3) // jcxz, jecxz
                {
                    bDone=false;
                    break;
                }
				else
				{
                    LPVOID lpTmpAddr=0;
#ifdef _AMD64_
                    lpTmpAddr=&lpTable[dwTmpAddrsCount++];
                    if (dwTmpAddrsCount > MAX_JUMPS)
                        break;
#endif
					AppendTempAddress(lpDest,dwNewPos,&jcc,&TmpAddr[dwTmpAddrCount++],(void **)lpTmpAddr);
                    if (dwTmpAddrCount > MAX_JUMPS)
                        break;

					SetJccOpcode(&hs,&jcc);
					lpCopySrc=&jcc;
					dwCopySize=sizeof(jcc);
				}
			}
			else if (((hs.opcode & 0xFE) == 0xC2) || // ret
                     ((hs.opcode & 0xFD) == 0xE9) || // jmp rel
                     (((hs.modrm & 0xC7) == 0x05) && ((hs.opcode == 0xFF) && (hs.modrm_reg == 4))) || // jmp rip
                     ((hs.opcode == 0xFF) && (hs.opcode2 == 0x25))) // jmp abs
				bDone=((ULONG_PTR)lpInst >= dwJmpDest);

			if (((ULONG_PTR)lpInst < dwJmpDest) && (dwCopySize != hs.len))
			{
			    bDone=false;
				break;
			}

			memcpy((byte*)lpBridge+dwNewPos,lpCopySrc,dwCopySize);

			dwOldPos+=hs.len;
			dwNewPos+=dwCopySize;
		}

		if (bDone)
        {
            memcpy(lpBackup,lpFunc,dwOldPos);
            *dwBackupCodeSize=dwOldPos;
#ifdef _AMD64_
            int dwAddrTblPos=0;
#endif
            for (int i=0; i < dwTmpAddrCount; i++)
            {
                LPVOID lpAddr;
#ifdef _AMD64_
                if ((ULONG_PTR)TmpAddr[i].lpAddress < 0x10000)
                    lpAddr=&lpTable[dwAddrTblPos++];
                else
#endif
                    lpAddr=TmpAddr[i].lpAddress;
                byte *lpTrampoline=(byte*)lpBridge;
                *(DWORD*)(lpTrampoline+TmpAddr[i].dwPosition)=(DWORD)lpAddr-((DWORD)lpBridge+TmpAddr[i].dwPc);
            }
            return lpBridge;
        }
        else
            MemFree(lpBridge);
    }
    return NULL;
}
//根据相同版本下与SSDT地址存在的偏移获取的SSDT SHADOW的地址
// WinDbg 下 ?KeServiceDescriptorTable-
// 会打印出:Evaluate expression: 64 = 00000040(XP), -0xE0(2K)
//卡巴斯基有个类似的函数:FindSystemServiceDescriptionTableShadow
SYSTEM_SERVICE_TABLE *GetKeServiceDescriptorTableShadowX86()
{ 
    //通过搜索 操作SSDT的函数实现中的有效内存地址的办法 来查找 Shadow SSDT
    // First, obtain a pointer to KeAddSystemServiceTable
    unsigned char *check = (unsigned char*)KeAddSystemServiceTable; 
    int i;
    //Initialize an instance of System Service Table, will be used to
    //obtain an address from KeAddSystemServiceTable
    SYSTEM_SERVICE_TABLE *rc=0; 

	KdPrint(("GetKeServiceDescriptorTableShadowX86, KeAddSystemServiceTable=%p\n", check));

	// Make 100 attempts to match a valid address with that of KeServiceDescriptorTable 
    for (i=0; i<4096; i++) {  //PAGE_SIZE
        __try { 
            // try to obtain an address from  KeAddSystemServiceTable 
            rc = *(SYSTEM_SERVICE_TABLE **)check; 
            // if this address is NOT valid OR it itself is the address of 
            //KeServiceDescriptorTable OR its first entry is NOT equal 
            //to the first entry of KeServiceDescriptorTable 
            if (!MmIsAddressValid (rc) 
                || (rc == (SYSTEM_SERVICE_TABLE *)KeServiceDescriptorTable) 
                || (memcmp (rc, KeServiceDescriptorTable, sizeof (*rc)) != 0)) { 
                    // Proceed with the next address 
                    check++; 
                    // don't forget to reset the old address 
                    rc = 0; 
            } 
        } __except (EXCEPTION_EXECUTE_HANDLER) 
        {
            rc = 0; 
        } 
        // when the loop is completed, check if it produced a valid address 
        if (rc) 
        {
            // because if it didn't, we failed to find the address of KeServiceDescriptorTableShadow 
            break; 
        }
    } 
    // otherwise, there is a valid address! So return it! 
    return rc; 

    //方法2
#if 0
    PUCHAR cPtr, pOpcode;
    ULONG Length = 0;

    for (cPtr = (PUCHAR)KeAddSystemServiceTable;
        cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
        cPtr += Length)
    {
        if (!MmIsAddressValid(cPtr)) break;

        Length = SizeOfCode(cPtr, &pOpcode);

        if (!Length || (Length == 1 && *pOpcode == 0xC3)) break;

        //找到以下汇编对应的位置: 
        //805ba5a3 8d8840a65580    lea    ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
        if (*(PUSHORT)pOpcode == 0x888D)
        {
            KeServiceDescriptorTableShadow = *(PVOID *)(pOpcode + 2);
            break;
        }
    }
#endif 
}