예제 #1
0
파일: etc.cpp 프로젝트: jchristi/taddraw
	int GetMinValidLenWithMatchOpcode ( LPBYTE OrgOpcode_Pb, int AtLeastLen_I)
	{//得到一个最少长为AtLeastLen_I的按opcode来的长度。
		if (NULL==OrgOpcode_Pb)
		{
			return 0;
		}
		int RtnLen_I= 0;
		while (AtLeastLen_I>(RtnLen_I+= GetOpCodeSize ( OrgOpcode_Pb+ RtnLen_I)));
		return RtnLen_I;
	}
예제 #2
0
BOOL IsSystemCall(PVOID Routine)
{
    PBYTE Buffer;

    Buffer = (PBYTE)Routine;

    if (Buffer[0] == 0xB8)
        return TRUE;

    for (ULONG_PTR Count = 1; Count != 0; --Count)
    {
        Buffer += GetOpCodeSize(Buffer);
        if (Buffer[0] == 0xB8)
            return TRUE;
    }

    return FALSE;
}
예제 #3
0
HANDLE
NTAPI
QqCreateWaitQQProtectThread(
    PSECURITY_ATTRIBUTES    ThreadAttributes,
    ULONG_PTR               StackSize,
    PTHREAD_START_ROUTINE   StartAddress,
    PVOID                   Parameter,
    ULONG                   CreationFlags,
    PULONG                  ThreadId
)
{
    NTSTATUS    Status;
    PVOID       Ebp, CallCreateQQProtectExchangeWindow;
    PROCESS_BASIC_INFORMATION BasicInfo;

    LOOP_ONCE
    {
        if (PtrAnd(Parameter, 0xFFF00000) != 0)
            continue;

        Status = NtQueryInformationProcess((HANDLE)Parameter, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), nullptr);
        FAIL_BREAK(Status);

        if (BasicInfo.UniqueProcessId != CurrentPid())
            break;

        AllocStack(16);
        Ebp = *((PVOID *)_AddressOfReturnAddress() - 1);

        CallCreateQQProtectExchangeWindow = *((PVOID *)Ebp + 1);
        if (*(PBYTE)CallCreateQQProtectExchangeWindow != CALL)
            break;

        NtClose((HANDLE)Parameter);

        *(PULONG_PTR)((PVOID *)Ebp + 1) += GetOpCodeSize(CallCreateQQProtectExchangeWindow);

        return nullptr;
    }

    return HummerCreateThread(ThreadAttributes, StackSize, StartAddress, Parameter, CreationFlags, ThreadId);
}
예제 #4
0
파일: etc.cpp 프로젝트: jchristi/taddraw
	DWORD X86RedirectOpcodeToNewBase (LPVOID NewBase, LPBYTE OrgOpcode, DWORD * LenOfOpcode_Dw, LPBYTE * Rtn_PPb)
	{//把一段opcode中的jcc和call受代码地址影响的code都处理成新地址的。返回的Rtn_PPb是需要用delete []删除的。
		DWORD ValidOpcodeLen= GetMinValidLenWithMatchOpcode ( OrgOpcode, *LenOfOpcode_Dw);
		DWORD tempOpcodeOff_Dw= 0;

		DWORD PureJmpAddr_Dw= 0;
		LPBYTE RtnBuffer= new BYTE[*LenOfOpcode_Dw* 4];//全部都是jecxz也最多只会扩大4倍。
		LPBYTE PtrIn_RtnBuffer= RtnBuffer;
		int tempForOpcodeLen= 0;

		int diffFromNewBaseAndRtnBuffer_I= (int)(RtnBuffer- (LPBYTE)NewBase);
		while (tempOpcodeOff_Dw<ValidOpcodeLen)
		{
			tempForOpcodeLen= GetOpCodeSize ( OrgOpcode+ tempOpcodeOff_Dw);
			switch (X86ShallToRedirect ( OrgOpcode+ tempOpcodeOff_Dw, OrgOpcode+ tempOpcodeOff_Dw, &PureJmpAddr_Dw, OrgOpcode, ValidOpcodeLen))
			{
			case -1:
				//jcc的需要根据不同opcode来处理:
				switch ((OrgOpcode+ tempOpcodeOff_Dw)[0])
				{
				case 0x0f:
					memcpy ( PtrIn_RtnBuffer, OrgOpcode+ tempOpcodeOff_Dw, 2);
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 2;
					*((PDWORD)(PtrIn_RtnBuffer))= PureJmpAddr_Dw- ((DWORD)PtrIn_RtnBuffer- 2- diffFromNewBaseAndRtnBuffer_I)- 6;
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 4;
					break;

				case 0xe3:
					//这个很特殊,判断ecx的jecxz没有长跳转
					//用 85 c9 test ecx, ecx 
					//   0f 84 00000000 je addr来代替
					PtrIn_RtnBuffer[0]= 0x85;
					PtrIn_RtnBuffer[1]= 0xc9;
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 2;

					PtrIn_RtnBuffer[0]= 0x0f;
					PtrIn_RtnBuffer[1]= 0x84;

					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 2;

					*((PDWORD)(PtrIn_RtnBuffer))= PureJmpAddr_Dw- ((DWORD)PtrIn_RtnBuffer- 2- diffFromNewBaseAndRtnBuffer_I)- 6;
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 4;
					break;

				default:
					//在default里也处理 0x7?的情况。
					//这儿替换成对应的 0f 8?
					PtrIn_RtnBuffer[0]= 0x0f;
					PtrIn_RtnBuffer[1]= static_cast <BYTE> (0x80| (0xf& (OrgOpcode+ tempOpcodeOff_Dw)[0]));

					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 2;

					*((PDWORD)(PtrIn_RtnBuffer))= PureJmpAddr_Dw- ((DWORD)PtrIn_RtnBuffer- 2- diffFromNewBaseAndRtnBuffer_I)- 6;
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 4;
					break;
				case 0xeb:
					//*不能动orgopcode,其实只是改成0xeb,然后和jmp一样处理。*//
					//
					*PtrIn_RtnBuffer= 0xe9;
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 1;
					*(DWORD *) (PtrIn_RtnBuffer)= PureJmpAddr_Dw- ((DWORD)PtrIn_RtnBuffer- 1- diffFromNewBaseAndRtnBuffer_I)- 5;
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 4;
					break;
				case 0xe9:
					*PtrIn_RtnBuffer= *(OrgOpcode+ tempOpcodeOff_Dw);
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 1;
					*(DWORD *) (PtrIn_RtnBuffer)= PureJmpAddr_Dw- ((DWORD)PtrIn_RtnBuffer- 1- diffFromNewBaseAndRtnBuffer_I)- 5;
					PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 4;
					//*32bits的jmp,可以和call那个一样处理*//
					//
				}
				break;
			case 1:
				//call的话,直接重新设置要跳转的地址就可以了。
				*PtrIn_RtnBuffer= *(OrgOpcode+ tempOpcodeOff_Dw);
				PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 1;
				*(DWORD *) (PtrIn_RtnBuffer)= PureJmpAddr_Dw- ((DWORD)PtrIn_RtnBuffer- 1- diffFromNewBaseAndRtnBuffer_I)- 5;
				PtrIn_RtnBuffer= PtrIn_RtnBuffer+ 4;
				break;
			case 0:
				memcpy ( PtrIn_RtnBuffer, OrgOpcode+ tempOpcodeOff_Dw, tempForOpcodeLen);
				PtrIn_RtnBuffer= PtrIn_RtnBuffer+ tempForOpcodeLen;
				break;
			}

			tempOpcodeOff_Dw+= tempForOpcodeLen;
		}

		//tempOpcodeOff_Dw+= tempForOpcodeLen;
		*LenOfOpcode_Dw= tempOpcodeOff_Dw;

		*Rtn_PPb= RtnBuffer;

		return (DWORD)(PtrIn_RtnBuffer- RtnBuffer);
	}