Exemplo n.º 1
0
/******************************************************************
 *		addr_to_linear
 *
 * converts an address into its linear value
 */
DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr)
{
    LDT_ENTRY	le;

    switch (addr->Mode)
    {
    case AddrMode1616:
        if (GetThreadSelectorEntry(hThread, addr->Segment, &le))
            return (le.HighWord.Bits.BaseHi << 24) + 
                (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + LOWORD(addr->Offset);
        break;
    case AddrMode1632:
        if (GetThreadSelectorEntry(hThread, addr->Segment, &le))
            return (le.HighWord.Bits.BaseHi << 24) + 
                (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + addr->Offset;
        break;
    case AddrModeReal:
        return (DWORD)(LOWORD(addr->Segment) << 4) + addr->Offset;
    case AddrModeFlat:
        return addr->Offset;
    default:
        FIXME("Unsupported (yet) mode (%x)\n", addr->Mode);
        return 0;
    }
    FIXME("Failed to linearize address %04x:%08lx (mode %x)\n",
          addr->Segment, addr->Offset, addr->Mode);
    return 0;
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
    HANDLE hEvent = CreateEvent(nullptr, FALSE, FALSE, L"Useless event");

    HANDLE hThread1 = CreateThread(nullptr, 0, &ThreadEntry, hEvent, 0, nullptr);
    HANDLE hThread2 = CreateThread(nullptr, 0, &ThreadEntry, hEvent, 0, nullptr);
    HANDLE hThread3 = CreateThread(nullptr, 0, &ThreadEntry, hEvent, 0, nullptr);

    CONTEXT ctxThread1 = { CONTEXT_ALL };
    (void)GetThreadContext(hThread1, &ctxThread1);

    CONTEXT ctxThread2 = { CONTEXT_ALL };
    (void)GetThreadContext(hThread2, &ctxThread2);

    CONTEXT ctxThread3 = { CONTEXT_ALL };
    (void)GetThreadContext(hThread3, &ctxThread3);

    LDT_ENTRY ldtThread1 = { 0 };
    LDT_ENTRY ldtThread2 = { 0 };
    LDT_ENTRY ldtThread3 = { 0 };

    (void)GetThreadSelectorEntry(hThread1, ctxThread1.SegFs, &ldtThread1);
    (void)GetThreadSelectorEntry(hThread2, ctxThread2.SegFs, &ldtThread2);
    (void)GetThreadSelectorEntry(hThread3, ctxThread3.SegFs, &ldtThread3);

    NT_TIB *pTibMain = (NT_TIB *)__readfsdword(0x18);

    DWORD_PTR dwFSBase1 = (ldtThread1.HighWord.Bits.BaseHi << 24) |
                          (ldtThread1.HighWord.Bits.BaseMid << 16) |
                          ldtThread1.BaseLow;

    DWORD_PTR dwFSBase2 = (ldtThread2.HighWord.Bits.BaseHi << 24) |
                          (ldtThread2.HighWord.Bits.BaseMid << 16) |
                          ldtThread2.BaseLow;

    DWORD_PTR dwFSBase3 = (ldtThread3.HighWord.Bits.BaseHi << 24) |
                          (ldtThread3.HighWord.Bits.BaseMid << 16) |
                          ldtThread3.BaseLow;

    fprintf(stderr, "Thread 1 FS Segment base address: %X\n"
            "Thread 2 FS Segment base address : %X\n"
            "Thread 3 FS Segment base address : %X\n",
            dwFSBase1, dwFSBase2, dwFSBase3);

    DWORD_PTR dwWOW64Address1 = *(DWORD_PTR *)((unsigned char *)dwFSBase1 + 0xC0);
    DWORD_PTR dwWOW64Address2 = *(DWORD_PTR *)((unsigned char *)dwFSBase2 + 0xC0);
    DWORD_PTR dwWOW64Address3 = *(DWORD_PTR *)((unsigned char *)dwFSBase3 + 0xC0);

    fprintf(stderr, "Thread 1 FS:[0xC0] : %X\n"
            "Thread 2 FS:[0xC0] : %X\n"
            "Thread 3 FS:[0xC0] : %X\n",
            dwWOW64Address1, dwWOW64Address2, dwWOW64Address3);

    return 0;
}
Exemplo n.º 3
0
ESTATUS main_GetThreadTebAddress(HANDLE hThread, PVOID *ppvTebAddress)
{
	ESTATUS eReturn = ESTATUS_INVALID;
	CONTEXT tContext = { 0 };
	BOOL bErr = FALSE;
	LDT_ENTRY tLdtEnry = { 0 };
	PVOID pvTebAddress;

	eReturn = main_GetThreadContext(hThread, CONTEXT_SEGMENTS, &tContext);
	if (ESTATUS_FAILED(eReturn))
	{
		goto lblCleanup;
	}

	bErr = GetThreadSelectorEntry(hThread, tContext.SegFs, &tLdtEnry);
	if (FALSE == bErr)
	{
		eReturn = ESTATUS_MAIN_GETTHREADTEBADDRESS_GETTHREADSELECTORENTRY_FAILED;
		goto lblCleanup;
	}

	pvTebAddress = (PVOID)(
		(tLdtEnry.BaseLow) | 
		(tLdtEnry.HighWord.Bytes.BaseMid << 0x10) | 
		(tLdtEnry.HighWord.Bytes.BaseHi << 0x18)
		);

	*ppvTebAddress = pvTebAddress;
	eReturn = ESTATUS_SUCCESS;

lblCleanup:
	return eReturn;

}
Exemplo n.º 4
0
// This is an GDT/LDT selector (pGDT+Selector)
BYTE *GetAbsoluteAddressFromSelector(WORD Selector, DWORD Offset)
{
	DESCRIPTOR_ENTRY Entry;
	GATE_ENTRY *Gate;
	ULONG_PTR Base;
	
	assert(Selector < 0x10000);
	if (!GetThreadSelectorEntry(GetCurrentThread(), Selector, (LDT_ENTRY *)&Entry)) return NULL;
	if (!Entry.Present) return NULL;
	if (Entry.System)
	{
		Base = 0;
#ifdef _WIN64
		Base |= (ULONG_PTR)Entry.HighOffset64 << 32;
#endif
		Base |= Entry.BaseHi << 24;
		Base |= Entry.BaseMid << 16;
		Base |= Entry.BaseLow;
	}
	else
	{
		switch (Entry.Type)
		{
			case 1: // 16-bit TSS (available)
			case 2: // LDT
			case 3: // 16-bit TSS (busy)
			case 9: // 32-bit TSS (available)
			case 11: // 32-bit TSS (busy)
				Base = 0;
#ifdef _WIN64
				Base |= (ULONG_PTR)Entry.HighOffset64 << 32;
#endif
				Base |= Entry.BaseHi << 24;
				Base |= Entry.BaseMid << 16;
				Base |= Entry.BaseLow;
				break;

			case 4: // 16-bit call gate
			case 5: // task gate
			case 6: // 16-bit interrupt gate
			case 7: // 16-bit task gate
			case 12: // 32-bit call gate
			case 14: // 32-bit interrupt gate
			case 15: // 32-bit trap gate
				Gate = (GATE_ENTRY *)&Entry;
#ifdef _WIN64
				Base = ((ULONG_PTR)Gate->HighOffset64 << 32) | (Gate->HighOffset << 16) | Gate->LowOffset;
#else
				Base = (Gate->HighOffset << 16) | Gate->LowOffset;
#endif
				assert(!Offset); Offset = 0;
				break;
			default:
				assert(0);
				return NULL;
		}
	}
	return (BYTE *)Base + Offset;
}
Exemplo n.º 5
0
/// <summary>
/// Gets the main TLS address (optionally with an offset added)
/// </summary>
/// <param name="offset">The offset to add to the TLS address.</param>
/// <returns>A Pointer to the TLS.</returns>
Pointer Engine::GetMainTls(size_t offset)
{
	static Pointer ThreadLocalStorage;
	if (!ThreadLocalStorage && GetGameThreadID())
	{
		size_t MainThreadID = GetGameThreadID();

		HANDLE MainThreadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, false, MainThreadID);

		// Get thread context
		CONTEXT MainThreadContext;
		MainThreadContext.ContextFlags = CONTEXT_FULL;

		if (MainThreadID != GetCurrentThreadId())
			SuspendThread(MainThreadHandle);

		BOOL success = GetThreadContext(MainThreadHandle, &MainThreadContext);
		if (!success)
		{
			OutputDebugStringA(std::string("Error getting thread context: ").append(std::to_string(GetLastError())).c_str());
			std::exit(1);
		}
		ResumeThread(MainThreadHandle);

		// Get thread selector

		LDT_ENTRY MainThreadLdt;

		success = GetThreadSelectorEntry(MainThreadHandle, MainThreadContext.SegFs, &MainThreadLdt);
		if (!success)
		{
			OutputDebugStringA(std::string("Error getting thread context: ").append(std::to_string(GetLastError())).c_str());
		}
		size_t TlsPtrArrayAddress = (size_t)((size_t)(MainThreadLdt.HighWord.Bits.BaseHi << 24) | (MainThreadLdt.HighWord.Bits.BaseMid << 16) | MainThreadLdt.BaseLow) + 0x2C;
		size_t TlsPtrAddress = Pointer(TlsPtrArrayAddress).Read<uint32_t>();

		// Index has been consistantly 0. Keep a look out.
		ThreadLocalStorage = Pointer(TlsPtrAddress)[0];
	}

	return ThreadLocalStorage(offset);
}
Exemplo n.º 6
0
BOOL GetDescriptorData(
    WORD selector,
    LPVDMLDT_ENTRY pdte
    )
{
#ifdef i386

    LDT_ENTRY  dte;
    if (!GetThreadSelectorEntry( hCurrentThread,
                                    selector,
                                   &dte)) {
        return( FALSE );
    }
    pdte->HighWord = dte.HighWord;
    pdte->BaseLow = dte.BaseLow;
    pdte->LimitLow = dte.LimitLow;
    return (TRUE);

#else
    PVOID LdtAddress;
    NTSTATUS                Status;
    selector &= ~(SELECTOR_LDT | SELECTOR_RPL);

    //
    // Get address of Ldt
    //

    LdtAddress = (PVOID)EXPRESSION("ntvdm!Ldt");

    Status = READMEM(LdtAddress, &LdtAddress, sizeof(ULONG));

    if (!Status) {
        return FALSE;
    }

    (PUCHAR)LdtAddress += selector;

    Status = READMEM(LdtAddress, pdte, sizeof(VDMLDT_ENTRY));

    return Status;
#endif
}
Exemplo n.º 7
0
BOOL IsBigSel( WORD sel )
{
#if defined( MD_axp ) | defined( MD_ppc )
    return( TRUE );
#elif defined( MD_x86 ) || defined( MD_x64 )
    thread_info *ti;
    LDT_ENTRY   ldt;

    if( sel == FlatCS || sel == FlatDS ) {
        return( TRUE );
    }
    ti = FindThread( DebugeeTid );
    if( ti == NULL ) {
        return( TRUE );
    }
    GetThreadSelectorEntry( ti->thread_handle, sel, &ldt );
    return( ldt.HighWord.Bits.Default_Big );
#else
   #error IsBigSel not configured
#endif
}
Exemplo n.º 8
0
static unsigned long
get_ds_base (void)
{
  unsigned short dsval;
  LDT_ENTRY ldt;
  unsigned long dsbase;

  __asm
    {
      mov dsval,ds
    }

  dsbase = 0;

  GetThreadSelectorEntry (GetCurrentThread(), dsval, &ldt);

  dsbase = ldt.HighWord.Bits.BaseHi << 24 | ldt.HighWord.Bits.BaseMid << 16
	     | ldt.BaseLow;

  return dsbase;
}
Exemplo n.º 9
0
void main(void)
{
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
CONTEXT context;
LDT_ENTRY sel;
DWORD read,tib,peb,exebase,peoffs,ep;
IMAGE_NT_HEADERS pehdr;
int len;
char sessmgr[MAX_PATH+13];
char buffer[2048];

GetSystemDirectory(sessmgr,MAX_PATH);
sessmgr[MAX_PATH]=0;
strcat(sessmgr,"\\sessmgr.exe");
memset(&sinfo,0,sizeof(sinfo));
sinfo.cb=sizeof(sinfo);

if (!CreateProcess(sessmgr,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&sinfo,&pinfo))
printf("createprocess failed"), exit(1);

context.ContextFlags=CONTEXT_FULL;
GetThreadContext(pinfo.hThread,&context);
GetThreadSelectorEntry(pinfo.hThread,context.SegFs,&sel);
tib=sel.BaseLow|(sel.HighWord.Bytes.BaseMid<<16)|(sel.HighWord.Bytes.BaseHi<<24);
ReadProcessMemory(pinfo.hProcess,(LPCVOID)(tib+0x30),&peb,4,&read);
ReadProcessMemory(pinfo.hProcess,(LPCVOID)(peb+0x08),&exebase,4,&read);

ReadProcessMemory(pinfo.hProcess,(LPCVOID)(exebase+0x3C),&peoffs,4,&read);
ReadProcessMemory(pinfo.hProcess,(LPCVOID)(exebase+peoffs),&pehdr,sizeof(pehdr),&read);
ep=exebase+pehdr.OptionalHeader.AddressOfEntryPoint;

len=injcode(buffer);
VirtualProtect((LPVOID)ep,len,PAGE_EXECUTE_READWRITE,&read);
WriteProcessMemory(pinfo.hProcess,(LPVOID)ep,buffer,len,&read);

ResumeThread(pinfo.hThread);
}
Exemplo n.º 10
0
void NaClLdtPrintSelector(uint16_t selector) {
    /* type_name converts the segment type into print name */
    static const char* type_name[] = {
        "data read only",
        "data read_only accessed",
        "data read write",
        "data read write accessed",
        "data read expand",
        "data read expand accessed",
        "data read write expand",
        "data read write expand accessed",
        "code execute",
        "code execute accessed",
        "code execute read",
        "code execute read accessed",
        "code execute conforming",
        "code execute conforming accessed",
        "code execute read conforming",
        "code execute read conforming accessed"
    };

    struct LdtEntry entry;
    int retval;

    /*
     * Try the first method, using GetThreadSelectorEntry.
     */
    retval = GetThreadSelectorEntry(GetCurrentThread(), selector,
                                    (LPLDT_ENTRY)&entry);
    if (0 != retval) {
        /*
         * Failed to get the entry.  Try using query_information_process.
         */
        DWORD len;
        LdtInfo info;
        memset(&info, 0, sizeof(LdtInfo));
        info.byte_offset = selector & ~0x7;
        info.size = sizeof(struct LdtEntry);
        retval = query_information_process((HANDLE)-1, 10, (void*)&info, 16, &len);
        if (0 != retval) {
            return;
        }
        entry = info.entries[0];
    }

    printf("DESCRIPTOR for selector %04x\n", selector);
    /* create functions to do base, limit, and type */
    printf("  base        %08x\n", (entry.base_24to31 << 24)
           | (entry.base_16to23 << 16) | entry.base_00to15);
    printf("  limit       %08x%s\n",
           (((entry.limit_16to19 << 16) | entry.limit_00to15)
            << (entry.granularity ? 12 : 0)),
           (entry.granularity ? " (page granularity)" : ""));
    printf("  type        %s, %s\n", ((entry.type & 0x10) ? "user" : "system"),
           type_name[entry.type & 0xf]);
    printf("  privilege   %d\n", entry.descriptor_privilege);
    printf("  present %s\n", (entry.present ? "yes" : "no"));
    printf("  available %s\n", (entry.available ? "yes" : "no"));
    printf("  64-bit code %s\n", (entry.code_64_bit ? "yes" : "no"));
    printf("  op size %s\n", (entry.op_size_32 ? "32" : "16"));
}
Exemplo n.º 11
0
BOOL
TranslateAddress(
    HPRCX  hprc,
    HTHDX  hthd,
    LPADDR lpaddr,
    BOOL   f16ToFlat
    )

/*++

Routine Description:

    This function is used to preform address translations from the segmented
    to the flat world and back again.

Arguments:

    hprc        - Supplies the handle to the current process

    hthd        - Supplies the handle to the thread for the address

    lpaddr      - Supplies the address to be translated

    f16ToFlat   - Supplies the direction the translation is to be made

Return Value:

    TRUE on success and FALSE on failure

--*/

{
#if defined(i386)
    LDT_ENTRY   ldt;
    ULONG       ul;

#ifdef WIN32S
    ADDR_IS_FLAT(*lpaddr) = TRUE;
    ADDR_IS_REAL(*lpaddr) = FALSE;
    return TRUE;
#endif

    /*
     *  Step 0.  If the address has already been mapped flat then return
     */

    if (ADDR_IS_FLAT(*lpaddr)) {
        return TRUE;
    }

    /*
     *  Step 1.  Is to find a stopped thread.  This is mainly for WOW support
     *          where the lack of a stopped thread is a serious thing,
     *          we can not do anything smartly with wow if this is the
     *          case.   We will currently only search for a single
     *          stopped thread cause the blasted operating system won't
     *          let us have more than one.
     */

    if (hthd == 0) {
        for (hthd = hprc->hthdChild; hthd != hthdxNull; hthd = hthd->nextSibling) {
            if (hthd->tstate & ts_stopped) {
                break;
            }
        }

        if (hthd == 0) {
            hthd = hprc->hthdChild;
        }
    }

    /*
     *  Must have a thread
     */

    if (hthd == NULL) {
        return FALSE;
    }

    /*
     *  Step 2. Depending on if the last event was WOW we need to
     *          either go in with a WOW remap or do the standard
     *          non-wow remap
     */

    if (hthd->fAddrIsFlat) {
        if (ADDR_IS_REAL( *lpaddr )) {
            ul = GetAddrSeg(*lpaddr) * 16 + (DWORD)GetAddrOff(*lpaddr);
            lpaddr->addr.off = ul;
        } else if (GetThreadSelectorEntry(hthd->rwHand, GetAddrSeg(*lpaddr),
                                          &ldt)) {
            ul = (ldt.HighWord.Bytes.BaseHi << 24) |
                 (ldt.HighWord.Bytes.BaseMid << 16) |
                 (ldt.BaseLow);
            lpaddr->addr.off += ul;
        } else {
            /*
             * Unrecognized selector
             */
            return FALSE;
        }
    } else {
#if defined(i386) && !defined(WIN32S)
        lpaddr->addr.off = (*pfnVDMGetPointer)(hprc->rwHand, hthd->rwHand,
                                         (WORD)GetAddrSeg(*lpaddr),
                                         (DWORD)GetAddrOff(*lpaddr),
                                         !lpaddr->mode.fReal);
#else  // defined(i386) && !defined(WIN32S)
        assert(FALSE);
        return FALSE;
#endif // defined(i386) && !defined(WIN32S)
    }
#endif
    ADDR_IS_FLAT(*lpaddr) = TRUE;
    ADDR_IS_REAL(*lpaddr) = FALSE;
    return TRUE;
}                               /* TranslateAddress() */