예제 #1
0
WORD SetupLDT(WORD seg, DWORD ldtbase)
{
   LDT_ENTRY EvilLdt;
   DWORD base = ldtbase;
   DWORD limit = 0;
   int ret;
  
   EvilLdt.BaseLow = base & 0xFFFF;
   EvilLdt.HighWord.Bytes.BaseMid = base >> 16;
   EvilLdt.HighWord.Bytes.BaseHi = base >> 24;
   EvilLdt.LimitLow = (limit >> 12) & 0xFFFF;
   EvilLdt.HighWord.Bits.LimitHi = limit >> 28;
   EvilLdt.HighWord.Bits.Granularity = 1; // 0/1, if 1, limit=(limit<<12)|FFF
   EvilLdt.HighWord.Bits.Default_Big = 1; // 0=16bit 1=32bit
   EvilLdt.HighWord.Bits.Reserved_0 = 0; // 0/1
   EvilLdt.HighWord.Bits.Sys = 0; // 0/1
   EvilLdt.HighWord.Bits.Pres = 1; // 0/1 (presence bit)
   EvilLdt.HighWord.Bits.Dpl = 3; // only 3 allowed :-(
   EvilLdt.HighWord.Bits.Type = 23; // [16..27]

   ret = NtSetLdtEntries( seg,
                    *(DWORD*)&EvilLdt,
                    *(((DWORD*)&EvilLdt)+1),
                    0,0,0);
   if (ret < 0) {
      printf("[-] Set ldt error : %08X.\n", ret);
      exit(0);
   }

   return seg;
}
NTSTATUS Dirtbox::AllocateLdtEntry(PWORD Selector, DWORD Base, DWORD LimitSize)
{
    DWORD Limit = Base + LimitSize;
    LDT_ENTRY LdtEntry;

    EnterCriticalSection(&ThreadingLock);

    // Locate a free LDT entry
    int i;
    for(i = 0; i < MAXIMUM_XBOX_THREADS; i++)
        if(FreeDescriptors[i])
            break;

    if(i == MAXIMUM_XBOX_THREADS)
    {
        LeaveCriticalSection(&ThreadingLock);
        DebugPrint("AllocateLdtEntry: Could not locate free LDT entry.");
        return STATUS_TOO_MANY_THREADS;
    }

    // Set up selector information
    LdtEntry.BaseLow                    = (WORD)(Base & 0xFFFF);
    LdtEntry.HighWord.Bits.BaseMid      = (Base >> 16) & 0xFF;
    LdtEntry.HighWord.Bits.BaseHi       = (Base >> 24) & 0xFF;
    LdtEntry.HighWord.Bits.Type         = 0x13; // RW data segment
    LdtEntry.HighWord.Bits.Dpl          = 3;    // user segment
    LdtEntry.HighWord.Bits.Pres         = 1;    // present
    LdtEntry.HighWord.Bits.Sys          = 0;
    LdtEntry.HighWord.Bits.Reserved_0   = 0;
    LdtEntry.HighWord.Bits.Default_Big  = 1;    // 386 segment
    LdtEntry.HighWord.Bits.Granularity  = 0;    // byte-level granularity

    LdtEntry.LimitLow                   = (WORD)(Limit & 0xFFFF);
    LdtEntry.HighWord.Bits.LimitHi      = (Limit >> 16) & 0xF;

    WORD Sel = ((i + 1) << 3) | 0x7;
    // Allocate selector
    NTSTATUS Res = NtSetLdtEntries(Sel, LdtEntry, 0, 0, 0);
    if(!NT_SUCCESS(Res))
    {
        LeaveCriticalSection(&ThreadingLock);
        DebugPrint("AllocateLdtEntry: Could not set LDT entries.");
        return Res;
    }

    FreeDescriptors[i] = FALSE;
    *Selector = Sel;
    LeaveCriticalSection(&ThreadingLock);

    return STATUS_SUCCESS;
}
NTSTATUS Dirtbox::FreeLdtEntry(WORD Selector)
{
    LDT_ENTRY LdtEntry;

    EnterCriticalSection(&ThreadingLock);

    memset(&LdtEntry, 0, sizeof(LDT_ENTRY));
    NTSTATUS Res = NtSetLdtEntries(Selector, LdtEntry, 0, 0, 0);
    if (!NT_SUCCESS(Res))
    {
        LeaveCriticalSection(&ThreadingLock);
        DebugPrint("FreeLdtEntry: Could not set LDT entries.");
        return Res;
    }
    FreeDescriptors[(Selector >> 3)-1] = TRUE;

    LeaveCriticalSection(&ThreadingLock);

    return STATUS_SUCCESS;
}