Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
9.0.0 KernelLoader IDA database
#define UNLOADED_FILE 1
#include <idc.idc>
static main(void)
{
// set 'loading idc file' mode
set_inf_attr(INF_GENFLAGS, INFFL_LOADIDC|get_inf_attr(INF_GENFLAGS));
GenInfo(); // various settings
Segments(); // segmentation
Enums(); // enumerations
Structures(); // structure types
ApplyStrucTInfos(); // structure type infos
Patches(); // manual patches
SegRegs(); // segment register values
Bytes(); // individual bytes (code,data)
Functions(); // function definitions
// clear 'loading idc file' mode
set_inf_attr(INF_GENFLAGS, ~INFFL_LOADIDC&get_inf_attr(INF_GENFLAGS));
}
//------------------------------------------------------------------------
// General information
static GenInfo(void) {
delete_all_segments(); // purge database
set_processor_type("ARM", SETPROC_USER);
set_inf_attr(INF_COMPILER, 6);
set_inf_attr(INF_STRLIT_BREAK, 0xA);
set_flag(INF_CMTFLAG, SW_ALLCMT, 0);
set_flag(INF_OUTFLAGS, OFLG_SHOW_VOID, 0);
set_inf_attr(INF_XREFNUM, 2);
set_flag(INF_OUTFLAGS, OFLG_SHOW_AUTO, 1);
set_inf_attr(INF_INDENT, 16);
set_inf_attr(INF_COMMENT, 40);
set_inf_attr(INF_MAXREF, 0x10);
add_default_til("gnulnx_arm64");
}
//------------------------------------------------------------------------
// Information about segmentation
static Segments(void) {
;
add_segm_ex(0X80315000,0X80317BEC,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80315000,".text");
SegClass (0X80315000,"CODE");
SegDefReg(0x80315000,"T",0x0);
SegDefReg(0x80315000,"DS",0x0);
set_segm_type(0X80315000,2);
add_segm_ex(0X80317BEC,0X80317BF0,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317BEC,".rodata");
SegClass (0X80317BEC,"CONST");
SegDefReg(0x80317BEC,"T",0x0);
SegDefReg(0x80317BEC,"DS",0x0);
set_segm_type(0X80317BEC,3);
add_segm_ex(0X80317BF0,0X80317C98,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317BF0,".rela.dyn");
SegClass (0X80317BF0,"CONST");
SegDefReg(0x80317BF0,"T",0x0);
SegDefReg(0x80317BF0,"DS",0x0);
set_segm_type(0X80317BF0,3);
add_segm_ex(0X80317C98,0X80317CD0,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317C98,".rodata.1");
SegClass (0X80317C98,"CONST");
SegDefReg(0x80317C98,"T",0x0);
SegDefReg(0x80317C98,"DS",0x0);
set_segm_type(0X80317C98,3);
add_segm_ex(0X80317CD0,0X80317D18,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317CD0,".dynsym");
SegClass (0X80317CD0,"CONST");
SegDefReg(0x80317CD0,"T",0x0);
SegDefReg(0x80317CD0,"DS",0x0);
set_segm_type(0X80317CD0,3);
add_segm_ex(0X80317D18,0X80317D19,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317D18,".dynstr");
SegClass (0X80317D18,"CONST");
SegDefReg(0x80317D18,"T",0x0);
SegDefReg(0x80317D18,"DS",0x0);
set_segm_type(0X80317D18,3);
add_segm_ex(0X80317D19,0X80317D30,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317D19,".rodata.2");
SegClass (0X80317D19,"CONST");
SegDefReg(0x80317D19,"T",0x0);
SegDefReg(0x80317D19,"DS",0x0);
set_segm_type(0X80317D19,3);
add_segm_ex(0X80317D30,0X80317E00,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317D30,".dynamic");
SegClass (0X80317D30,"DATA");
SegDefReg(0x80317D30,"T",0x0);
SegDefReg(0x80317D30,"DS",0x0);
set_segm_type(0X80317D30,3);
add_segm_ex(0X80317E00,0X80317E80,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317E00,".got");
SegClass (0X80317E00,"CONST");
SegDefReg(0x80317E00,"T",0x0);
SegDefReg(0x80317E00,"DS",0x0);
set_segm_type(0X80317E00,3);
add_segm_ex(0X80317E80,0X80317EB0,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317E80,".data");
SegClass (0X80317E80,"DATA");
SegDefReg(0x80317E80,"T",0x0);
SegDefReg(0x80317E80,"DS",0x0);
set_segm_type(0X80317E80,3);
add_segm_ex(0X80317EB0,0X80318EB0,0,2,1,2,ADDSEG_NOSREG);
SegRename(0X80317EB0,".bss");
SegClass (0X80317EB0,"BSS");
SegDefReg(0x80317EB0,"T",0x0);
SegDefReg(0x80317EB0,"DS",0x0);
set_segm_type(0X80317EB0,9);
add_segm_ex(0X80319008,0X80319009,0,1,1,2,ADDSEG_NOSREG);
SegRename(0X80319008,"UNDEF");
SegClass (0X80319008,"XTRN");
SegDefReg(0x80319008,"T",0x0);
SegDefReg(0x80319008,"DS",0x0);
set_segm_type(0X80319008,1);
set_inf_attr(INF_LOW_OFF, 0x80315000);
set_inf_attr(INF_HIGH_OFF, 0x80319009);
}
//------------------------------------------------------------------------
// Information about enum types
static Enums(void) {
auto id;
begin_type_updating(UTP_ENUM);
end_type_updating(UTP_ENUM);
}
static ApplyStrucTInfos_0(void) {
auto id;
id = get_struc_id("KInitialPageAllocator");
SetType(get_member_id(id, 0x0), "KInitialPageAllocator_vt *");
SetType(get_member_id(id, 0x8), "_QWORD");
id = get_struc_id("KernelMap");
SetType(get_member_id(id, 0x0), "_DWORD");
SetType(get_member_id(id, 0x4), "_DWORD");
SetType(get_member_id(id, 0x8), "_DWORD");
SetType(get_member_id(id, 0xC), "_DWORD");
SetType(get_member_id(id, 0x10), "_DWORD");
SetType(get_member_id(id, 0x14), "_DWORD");
SetType(get_member_id(id, 0x18), "_DWORD");
SetType(get_member_id(id, 0x1C), "_DWORD");
SetType(get_member_id(id, 0x20), "_DWORD");
SetType(get_member_id(id, 0x24), "_DWORD");
SetType(get_member_id(id, 0x28), "_DWORD");
SetType(get_member_id(id, 0x2C), "_DWORD");
id = get_struc_id("KInitialPageAllocator_vt");
SetType(get_member_id(id, 0x0), "void *(__cdecl *)(KInitialPageAllocator *)");
SetType(get_member_id(id, 0x8), "void (__cdecl *)(KInitialPageAllocator *)");
id = get_struc_id("KInitialPageTable");
SetType(get_member_id(id, 0x0), "void *");
SetType(get_member_id(id, 0x8), "_DWORD");
return id;
}
//------------------------------------------------------------------------
// Information about type information for structure members
static ApplyStrucTInfos() {
ApplyStrucTInfos_0();
}
static Structures_0(id) {
auto mid;
id = add_struc(-1,"KInitialPageAllocator",0);
id = add_struc(-1,"KernelMap",0);
id = add_struc(-1,"KInitialPageAllocator_vt",0);
id = add_struc(-1,"KInitialPageTable",0);
id = get_struc_id("KInitialPageAllocator");
mid = add_struc_member(id,"vtable", 0, 0x35500400, 0XFFFFFFFFFFFFFFFF, 8, 0XFFFFFFFFFFFFFFFF, 0, 0x000009);
mid = add_struc_member(id,"next_address", 0X8, 0x30000400, -1, 8);
set_struc_align(id,3);
id = get_struc_id("KernelMap");
mid = add_struc_member(id,"text_offset", 0, 0x20000400, -1, 4);
mid = add_struc_member(id,"text_end_offset", 0X4, 0x20000400, -1, 4);
mid = add_struc_member(id,"rodata_offset", 0X8, 0x20000400, -1, 4);
mid = add_struc_member(id,"rodata_end_offset", 0XC, 0x20000400, -1, 4);
mid = add_struc_member(id,"rwdata_offset", 0X10, 0x20000400, -1, 4);
mid = add_struc_member(id,"rwdata_end_offset", 0X14, 0x20000400, -1, 4);
mid = add_struc_member(id,"bss_offset", 0X18, 0x20000400, -1, 4);
mid = add_struc_member(id,"bss_end_offset", 0X1C, 0x20000400, -1, 4);
mid = add_struc_member(id,"ini1_end_offset", 0X20, 0x20000400, -1, 4);
mid = add_struc_member(id,"dynamic_end_offset", 0X24, 0x20000400, -1, 4);
mid = add_struc_member(id,"init_array_offset", 0X28, 0x20000400, -1, 4);
mid = add_struc_member(id,"init_array_end_offset", 0X2C, 0x20000400, -1, 4);
set_struc_align(id,2);
id = get_struc_id("KInitialPageAllocator_vt");
mid = add_struc_member(id,"Allocate", 0, 0x35500400, 0XFFFFFFFFFFFFFFFF, 8, 0XFFFFFFFFFFFFFFFF, 0, 0x000009);
mid = add_struc_member(id,"Free", 0X8, 0x35500400, 0XFFFFFFFFFFFFFFFF, 8, 0XFFFFFFFFFFFFFFFF, 0, 0x000009);
set_struc_align(id,3);
id = get_struc_id("KInitialPageTable");
mid = add_struc_member(id,"l1_table", 0, 0x35500400, 0XFFFFFFFFFFFFFFFF, 8, 0XFFFFFFFFFFFFFFFF, 0, 0x000009);
mid = add_struc_member(id,"num_l1_entries", 0X8, 0x20000400, -1, 4);
set_struc_align(id,3);
return id;
}
//------------------------------------------------------------------------
// Information about structure types
static Structures(void) {
auto id;
begin_type_updating(UTP_STRUCT);
id = Structures_0(id);
patch_byte (0X80316944, 0X1F);
patch_byte (0X80316945, 0X20);
patch_byte (0X80316946, 0X3);
patch_byte (0X80316947, 0XD5);
patch_byte (0X803169A4, 0X1F);
patch_byte (0X803169A5, 0X20);
patch_byte (0X803169A6, 0X3);
patch_byte (0X803169A7, 0XD5);
patch_byte (0X803169F8, 0X1F);
patch_byte (0X803169F9, 0X20);
patch_byte (0X803169FA, 0X3);
patch_byte (0X803169FB, 0XD5);
patch_byte (0X80316A34, 0X1F);
patch_byte (0X80316A35, 0X20);
patch_byte (0X80316A36, 0X3);
patch_byte (0X80316A37, 0XD5);
}
//------------------------------------------------------------------------
// Information about bytes
static Bytes_0(void) {
auto x;
#define id x
create_insn (x=0X80315000);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
set_name (0X80315000, "kernelldr_main");
create_insn (x=0X80315004);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X8031500C);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X8031502C);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80315034);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80315040);
op_stkvar (x, 1);
create_insn (x=0X80315044);
op_stkvar (x, 1);
set_cmt (0X80315048, "base_address", 0);
create_insn (x=0X80315048);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X8031504C);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
set_cmt (0X80315054, "dynamic", 0);
create_insn (x=0X80315064);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80315070);
op_stkvar (x, 1);
set_cmt (0X80315074, "ini1_base_address", 0);
create_insn (x=0X80315074);
op_stkvar (x, 1);
create_insn (x=0X8031507C);
op_stkvar (x, 1);
create_insn (x=0X80315084);
op_stkvar (x, 1);
create_insn (x=0X80315088);
op_stkvar (x, 1);
create_insn (0X80315094);
set_name (0X80315094, "kernelldr_save_tpidr_registers");
create_insn (0X803150C0);
set_name (0X803150C0, "kernelldr_verify_tpidr_el1");
create_insn (0X803150D4);
create_insn (0X80315800);
set_name (0X80315800, "synch_sp0_exception");
create_insn (0X80315804);
create_insn (0X80315880);
set_name (0X80315880, "irq_sp0_exception");
create_insn (0X80315884);
create_insn (0X80315900);
set_name (0X80315900, "fiq_sp0_exception");
create_insn (0X80315904);
create_insn (x=0X80315980);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
set_name (0X80315980, "serror_sp0_exception");
create_insn (0X80315984);
create_insn (0X80315A00);
set_name (0X80315A00, "synch_spx_exception");
create_insn (0X80315A04);
create_insn (0X80315A80);
set_name (0X80315A80, "irq_spx_exception");
create_insn (0X80315A84);
create_insn (0X80315B00);
set_name (0X80315B00, "fiq_spx_exception");
create_insn (0X80315B04);
create_insn (0X80315B80);
set_name (0X80315B80, "serror_spx_exception");
create_insn (0X80315B84);
create_insn (0X80315C00);
set_name (0X80315C00, "synch_a64_exception");
create_insn (0X80315C04);
create_insn (0X80315C80);
set_name (0X80315C80, "irq_a64_exception");
create_insn (0X80315C84);
create_insn (0X80315D00);
set_name (0X80315D00, "fiq_a64_exception");
create_insn (0X80315D04);
create_insn (0X80315D80);
set_name (0X80315D80, "serror_a64_exception");
create_insn (0X80315D84);
create_insn (0X80315E00);
set_name (0X80315E00, "synch_a32_exception");
create_insn (0X80315E04);
create_insn (0X80315E80);
set_name (0X80315E80, "irq_a32_exception");
create_insn (0X80315E84);
create_insn (0X80315F00);
set_name (0X80315F00, "fiq_a32_exception");
create_insn (0X80315F04);
create_insn (0X80315F80);
set_name (0X80315F80, "serror_a32_exception");
create_insn (0X80315F84);
set_name (0X80315F84, "synch_spx_exception_impl");
create_dword (0X80315FB4);
create_qword (0X80315FB8);
create_qword (0X80315FC0);
create_qword (0X80315FC8);
create_qword (0X80315FD0);
create_insn (x=0X80315FD8);
op_stkvar (x, 1);
set_name (0X80315FD8, "kernelldr_relocate_kernel_physically");
create_insn (x=0X80315FDC);
op_stkvar (x, 1);
create_insn (x=0X80315FE0);
op_stkvar (x, 1);
set_cmt (0X80315FEC, "b", 0);
create_insn (x=0X80316028);
op_stkvar (x, 1);
create_insn (x=0X8031602C);
op_stkvar (x, 1);
create_insn (x=0X80316030);
op_stkvar (x, 1);
create_insn (0X80316038);
set_name (0X80316038, "kernelldr_map_initial_identity_mapping");
create_insn (x=0X8031603C);
op_stkvar (x, 1);
create_insn (x=0X80316040);
op_stkvar (x, 1);
create_insn (x=0X80316044);
op_stkvar (x, 1);
create_insn (x=0X80316048);
op_stkvar (x, 1);
create_insn (x=0X8031604C);
op_stkvar (x, 1);
create_insn (x=0X80316084);
op_stkvar (x, 1);
set_cmt (0X80316094, "this", 0);
create_insn (x=0X80316094);
op_stkvar (x, 1);
set_cmt (0X8031609C, "attribute", 0);
create_insn (x=0X803160A0);
op_stkvar (x, 1);
set_cmt (0X803160A4, "address", 0);
set_cmt (0X803160A8, "size", 0);
create_insn (x=0X803160AC);
op_stkvar (x, 1);
set_cmt (0X803160B0, "phys_address", 0);
set_cmt (0X803160B4, "allocator", 0);
create_insn (x=0X803160BC);
op_stkvar (x, 1);
create_insn (x=0X803160C0);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X803160C4);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X803160C8);
op_hex (x, 1);
create_insn (x=0X803160CC);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X803160D0);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X803160D8);
op_hex (x, 1);
set_cmt (0X803160DC, "size", 0);
set_cmt (0X803160E0, "this", 0);
create_insn (x=0X803160E0);
op_stkvar (x, 1);
set_cmt (0X803160E4, "attribute", 0);
set_cmt (0X803160E8, "phys_address", 0);
set_cmt (0X803160EC, "allocator", 0);
set_cmt (0X803160FC, "this", 0);
create_insn (x=0X803160FC);
op_stkvar (x, 1);
set_cmt (0X80316100, "attribute", 0);
set_cmt (0X80316104, "address", 0);
create_insn (x=0X80316108);
op_stkvar (x, 1);
set_cmt (0X8031610C, "size", 0);
set_cmt (0X80316110, "phys_address", 0);
set_cmt (0X80316114, "allocator", 0);
create_insn (x=0X8031611C);
op_stkvar (x, 1);
set_cmt (0X80316148, "a1", 0);
create_insn (x=0X80316150);
op_hex (x, 1);
create_insn (x=0X80316170);
op_hex (x, 1);
create_insn (0X803161CC);
create_insn (x=0X80316254);
op_hex (x, 1);
create_insn (x=0X803162B0);
op_hex (x, 1);
create_insn (x=0X803162D8);
op_hex (x, 1);
create_insn (x=0X8031635C);
op_hex (x, 1);
create_insn (x=0X803163E0);
op_stkvar (x, 1);
create_insn (x=0X803163E4);
op_stkvar (x, 1);
create_insn (x=0X803163E8);
op_stkvar (x, 1);
create_insn (x=0X803163EC);
op_stkvar (x, 1);
create_insn (x=0X803163F0);
op_stkvar (x, 1);
create_insn (0X803163FC);
set_name (0X803163FC, "KInitialPageTable::Map");
create_insn (x=0X80316400);
op_stkvar (x, 1);
create_insn (x=0X80316404);
op_stkvar (x, 1);
create_insn (x=0X80316408);
op_stkvar (x, 1);
create_insn (x=0X8031640C);
op_stkvar (x, 1);
create_insn (x=0X80316410);
op_stkvar (x, 1);
create_insn (x=0X80316414);
op_stkvar (x, 1);
create_insn (x=0X80316430);
op_hex (x, 1);
create_insn (0X8031643C);
create_insn (x=0X8031645C);
op_hex (x, 1);
create_insn (x=0X80316460);
op_stkvar (x, 1);
create_insn (x=0X80316470);
op_hex (x, 1);
create_insn (x=0X8031648C);
op_hex (x, 1);
create_insn (x=0X803164B4);
op_stkvar (x, 1);
create_insn (x=0X803164D8);
op_hex (x, 1);
create_insn (x=0X803164E4);
op_hex (x, 1);
create_insn (x=0X803164EC);
op_hex (x, 1);
create_insn (x=0X803164FC);
op_hex (x, 1);
create_insn (x=0X80316524);
op_stkvar (x, 1);
create_insn (x=0X80316544);
op_hex (x, 1);
create_insn (x=0X80316550);
op_hex (x, 1);
create_insn (x=0X80316564);
op_hex (x, 1);
create_insn (0X80316580);
create_insn (x=0X80316588);
op_hex (x, 1);
create_insn (x=0X80316598);
op_hex (x, 1);
create_insn (0X803165C0);
create_insn (x=0X803165C8);
op_hex (x, 1);
create_insn (0X80316744);
create_insn (x=0X8031674C);
op_hex (x, 1);
create_insn (x=0X80316760);
op_hex (x, 1);
create_insn (0X8031677C);
create_insn (x=0X80316784);
op_hex (x, 1);
create_insn (x=0X803168E0);
op_stkvar (x, 1);
create_insn (x=0X803168E4);
op_stkvar (x, 1);
create_insn (x=0X803168E8);
op_stkvar (x, 1);
create_insn (x=0X803168EC);
op_stkvar (x, 1);
create_insn (x=0X803168F0);
op_stkvar (x, 1);
create_insn (x=0X803168F4);
op_stkvar (x, 1);
create_insn (x=0X80316900);
op_stkvar (x, 1);
set_name (0X80316900, "kernelldr_generate_random_range");
create_insn (x=0X80316904);
op_stkvar (x, 1);
create_insn (x=0X80316960);
op_stkvar (x, 1);
create_insn (x=0X80316964);
op_stkvar (x, 1);
create_insn (x=0X8031696C);
op_stkvar (x, 1);
set_name (0X8031696C, "kernelldr_should_reserve_additional_kernel_data");
create_insn (x=0X803169AC);
op_stkvar (x, 1);
create_insn (x=0X803169B4);
op_stkvar (x, 1);
set_name (0X803169B4, "kernelldr_get_adjusted_kernel_physical_base");
create_insn (x=0X803169B8);
op_stkvar (x, 1);
create_insn (x=0X80316A70);
op_stkvar (x, 1);
create_insn (x=0X80316A74);
op_stkvar (x, 1);
create_insn (x=0X80316A7C);
op_stkvar (x, 1);
set_name (0X80316A7C, "kernelldr_libc_init_array");
create_insn (x=0X80316A80);
op_stkvar (x, 1);
create_insn (x=0X80316A88);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316A8C);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316A90);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316A94);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316AA0);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316AA4);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316AB8);
op_stkvar (x, 1);
create_insn (x=0X80316ABC);
op_stkvar (x, 1);
create_insn (0X80316AC4);
set_name (0X80316AC4, "kernelldr_load_kernel");
create_insn (x=0X80316AC8);
op_stkvar (x, 1);
create_insn (x=0X80316ACC);
op_stkvar (x, 1);
create_insn (x=0X80316AD0);
op_stkvar (x, 1);
create_insn (x=0X80316AD4);
op_stkvar (x, 1);
create_insn (x=0X80316AD8);
op_stkvar (x, 1);
create_insn (x=0X80316ADC);
op_stkvar (x, 1);
create_insn (x=0X80316AE8);
op_stkvar (x, 1);
create_insn (x=0X80316AEC);
op_stkvar (x, 1);
set_cmt (0X80316AF0, "p_kernel_base", 0);
create_insn (x=0X80316AF0);
op_stkvar (x, 1);
set_cmt (0X80316AF4, "p_kernel_map", 0);
create_insn (x=0X80316AF4);
op_stkvar (x, 1);
create_insn (x=0X80316AF8);
op_stkvar (x, 1);
create_insn (x=0X80316B00);
op_stkvar (x, 1);
create_insn (x=0X80316B04);
op_hex (x, 1);
create_insn (x=0X80316B10);
op_stkvar (x, 1);
create_insn (x=0X80316B18);
op_hex (x, 1);
create_insn (0X80316B24);
create_insn (x=0X80316B28);
op_hex (x, 1);
create_insn (0X80316B34);
create_insn (x=0X80316B38);
op_hex (x, 1);
create_insn (0X80316B44);
create_insn (x=0X80316B48);
op_hex (x, 1);
create_insn (0X80316B54);
create_insn (x=0X80316B58);
op_hex (x, 1);
create_insn (0X80316B64);
create_insn (x=0X80316B68);
op_hex (x, 1);
create_insn (0X80316B74);
create_insn (x=0X80316B78);
op_stkvar (x, 1);
create_insn (x=0X80316B80);
op_stkvar (x, 1);
create_insn (x=0X80316B88);
op_stkvar (x, 1);
create_insn (x=0X80316B9C);
op_hex (x, 1);
create_insn (x=0X80316BA0);
op_stkvar (x, 1);
create_insn (0X80316BEC);
create_insn (x=0X80316BF0);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316BF4);
create_insn (x=0X80316BFC);
op_plain_offset (x, 1, 0X80317E80);
op_plain_offset (x, 129, 0X80317E80);
create_insn (x=0X80316C14);
op_stkvar (x, 1);
set_cmt (0X80316C20, "ttbr1_page_table", 0);
create_insn (x=0X80316C20);
op_stkvar (x, 1);
set_cmt (0X80316C24, "kernel_base", 0);
set_cmt (0X80316C28, "kernel_size", 0);
set_cmt (0X80316C2C, "page_tables_base", 0);
create_insn (x=0X80316C30);
op_stkvar (x, 1);
set_cmt (0X80316C34, "page_tables_size", 0);
set_cmt (0X80316C38, "allocator", 0);
create_insn (x=0X80316C40);
op_hex (x, 1);
create_insn (x=0X80316C50);
op_hex (x, 1);
set_cmt (0X80316C54, "_QWORD", 0);
set_cmt (0X80316C58, "_QWORD", 0);
create_insn (x=0X80316C60);
op_hex (x, 1);
create_insn (x=0X80316C7C);
op_stkvar (x, 1);
create_insn (x=0X80316C80);
op_stkvar (x, 1);
create_insn (x=0X80316CA0);
op_hex (x, 1);
create_insn (x=0X80316CC0);
op_hex (x, 1);
create_insn (x=0X80316CD0);
op_hex (x, 1);
create_insn (x=0X80316CF0);
op_hex (x, 1);
create_insn (x=0X80316D08);
op_hex (x, 1);
set_cmt (0X80316D24, "size", 0);
set_cmt (0X80316D30, "phys_address", 0);
create_insn (x=0X80316D34);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80316D38);
create_insn (x=0X80316D40);
op_stkvar (x, 1);
set_cmt (0X80316D44, "this", 0);
create_insn (x=0X80316D44);
op_stkvar (x, 1);
set_cmt (0X80316D48, "attribute", 0);
create_insn (x=0X80316D48);
op_stkvar (x, 1);
set_cmt (0X80316D4C, "address", 0);
set_cmt (0X80316D50, "allocator", 0);
set_cmt (0X80316D60, "phys_address", 0);
create_insn (x=0X80316D6C);
op_stkvar (x, 1);
set_cmt (0X80316D70, "this", 0);
create_insn (x=0X80316D70);
op_stkvar (x, 1);
set_cmt (0X80316D74, "attribute", 0);
create_insn (x=0X80316D74);
op_stkvar (x, 1);
set_cmt (0X80316D78, "address", 0);
set_cmt (0X80316D7C, "size", 0);
set_cmt (0X80316D80, "allocator", 0);
set_cmt (0X80316D88, "address", 0);
set_cmt (0X80316D8C, "size", 0);
set_cmt (0X80316D90, "phys_address", 0);
set_cmt (0X80316D94, "this", 0);
create_insn (x=0X80316D94);
op_stkvar (x, 1);
set_cmt (0X80316D98, "attribute", 0);
create_insn (x=0X80316D98);
op_stkvar (x, 1);
create_insn (x=0X80316D9C);
op_stkvar (x, 1);
set_cmt (0X80316DA0, "allocator", 0);
create_insn (x=0X80316DA8);
op_stkvar (x, 1);
create_insn (x=0X80316DBC);
op_stkvar (x, 1);
set_cmt (0X80316DC0, "dynamic", 0);
set_cmt (0X80316DC4, "base_address", 0);
set_cmt (0X80316DCC, "this", 0);
create_insn (x=0X80316DCC);
op_stkvar (x, 1);
set_cmt (0X80316DD0, "address", 0);
set_cmt (0X80316DD4, "size", 0);
create_insn (x=0X80316DDC);
op_stkvar (x, 1);
create_insn (x=0X80316DE4);
op_stkvar (x, 1);
create_insn (x=0X80316E08);
op_stkvar (x, 1);
create_insn (x=0X80316E0C);
op_stkvar (x, 1);
create_insn (x=0X80316E10);
op_stkvar (x, 1);
create_insn (x=0X80316E14);
op_stkvar (x, 1);
create_insn (x=0X80316E18);
op_stkvar (x, 1);
create_insn (x=0X80316E1C);
op_stkvar (x, 1);
create_insn (x=0X80316E28);
op_stkvar (x, 1);
set_name (0X80316E28, "KInitialPageTable::ReprotectToReadOnly");
create_insn (x=0X80316E2C);
op_stkvar (x, 1);
create_insn (x=0X80316E30);
op_stkvar (x, 1);
create_insn (x=0X80316E34);
op_stkvar (x, 1);
create_insn (x=0X80316E38);
op_stkvar (x, 1);
create_insn (x=0X80316E3C);
op_stkvar (x, 1);
create_insn (x=0X80316E48);
op_hex (x, 1);
create_insn (0X80316E54);
create_insn (x=0X80316E9C);
op_hex (x, 1);
create_insn (x=0X80316EB0);
op_hex (x, 1);
create_insn (x=0X80316ECC);
op_hex (x, 1);
create_insn (x=0X80316EDC);
op_hex (x, 1);
create_insn (x=0X80316EE4);
op_hex (x, 1);
create_insn (0X80317100);
create_insn (x=0X80317108);
op_hex (x, 1);
create_insn (x=0X80317110);
op_hex (x, 1);
create_insn (x=0X80317158);
op_hex (x, 1);
create_insn (x=0X8031716C);
op_hex (x, 1);
create_insn (x=0X80317184);
op_hex (x, 1);
create_insn (x=0X80317194);
op_hex (x, 1);
create_insn (x=0X8031719C);
op_hex (x, 1);
create_insn (0X803173B8);
create_insn (x=0X803173C0);
op_hex (x, 1);
create_insn (x=0X803173C8);
op_hex (x, 1);
create_insn (0X80317404);
create_insn (x=0X80317408);
op_hex (x, 1);
create_insn (x=0X80317410);
op_hex (x, 1);
create_insn (x=0X80317454);
op_stkvar (x, 1);
create_insn (x=0X80317458);
op_stkvar (x, 1);
create_insn (x=0X8031745C);
op_stkvar (x, 1);
create_insn (x=0X80317460);
op_stkvar (x, 1);
create_insn (x=0X80317464);
op_stkvar (x, 1);
create_insn (x=0X80317468);
op_stkvar (x, 1);
create_insn (0X80317470);
create_insn (0X80317474);
create_insn (0X80317478);
create_insn (0X8031747C);
create_insn (0X80317480);
create_insn (0X80317484);
create_insn (0X80317488);
create_insn (0X8031748C);
create_insn (0X80317490);
create_insn (0X80317494);
create_insn (0X80317498);
create_insn (0X8031749C);
create_insn (x=0X803174A0);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
set_name (0X803174A0, "kernelldr_finalize_initial_page_allocator");
create_insn (x=0X803174A4);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X803174A8);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X803174B0);
op_stkvar (x, 1);
set_name (0X803174B0, "KInitialPageAllocator::Allocate");
create_insn (x=0X803174B4);
op_stkvar (x, 1);
create_insn (x=0X803174DC);
op_stkvar (x, 1);
create_insn (x=0X803174E4);
op_stkvar (x, 1);
create_insn (0X803174EC);
create_insn (0X803174F0);
set_name (0X803174F0, "KInitialPageAllocator::Free");
create_insn (0X803174F4);
set_name (0X803174F4, "kernelldr_apply_relocations");
create_insn (x=0X80317520);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
create_insn (x=0X80317524);
set_cmt (0X80317538, "jumptable 0000000080317554 cases 1-6,8,10-16,18", 1);
create_insn (0X80317538);
create_insn (x=0X80317548);
op_plain_offset (x, 1, 0);
op_plain_offset (x, 129, 0);
set_cmt (0X80317554, "switch 20 cases ", 0);
set_cmt (0X80317558, "jumptable 0000000080317554 case 7", 1);
create_insn (0X80317558);
set_cmt (0X8031756C, "jumptable 0000000080317554 default case", 1);
set_cmt (0X80317590, "jumptable 0000000080317554 case 9", 1);
create_insn (0X80317590);
set_cmt (0X803175A4, "jumptable 0000000080317554 case 17", 1);
create_insn (0X803175A4);
set_cmt (0X803175BC, "jumptable 0000000080317554 case 19", 1);
create_insn (0X803175BC);
create_insn (0X803175D0);
set_cmt (0X803175D8, "jumptable 0000000080317554 case 0", 1);
create_insn (0X803175D8);
create_insn (0X80317644);
create_insn (0X80317648);
make_array (0X8031764C, 0X4);
create_insn (x=0X80317650);
op_stkvar (x, 1);
set_name (0X80317650, "memmove");
create_insn (x=0X80317654);
op_stkvar (x, 1);
create_insn (x=0X80317684);
op_hex (x, 1);
create_insn (0X803176B0);
create_insn (x=0X803176B8);
op_stkvar (x, 1);
create_insn (x=0X803176C0);
op_stkvar (x, 1);
create_insn (0X803176C8);
create_insn (x=0X803176EC);
op_stkvar (x, 1);
create_insn (x=0X803176F4);
op_stkvar (x, 1);
create_insn (x=0X803176FC);
op_hex (x, 1);
create_insn (x=0X80317714);
op_hex (x, 1);
create_insn (x=0X8031773C);
op_hex (x, 1);
create_insn (x=0X80317748);
op_hex (x, 1);
create_insn (x=0X8031776C);
op_hex (x, 1);
create_insn (0X8031777C);
create_insn (0X803177AC);
create_insn (0X803177B8);
set_name (0X803177B8, "memset");
create_insn (x=0X803177FC);
op_hex (x, 1);
create_insn (x=0X80317804);
op_hex (x, 1);
create_insn (x=0X80317814);
op_hex (x, 1);
create_insn (x=0X8031783C);
op_hex (x, 1);
create_insn (x=0X80317844);
op_hex (x, 1);
create_insn (0X80317888);
set_name (0X80317888, "memcpy");
create_insn (x=0X8031788C);
op_hex (x, 1);
create_insn (x=0X803178A8);
op_hex (x, 1);
create_insn (x=0X803178B0);
op_hex (x, 1);
create_insn (x=0X803178F4);
op_hex (x, 1);
create_insn (0X80317968);
create_insn (x=0X8031796C);
op_hex (x, 1);
create_insn (0X803179B4);
create_insn (0X803179F8);
create_insn (x=0X80317A04);
op_hex (x, 1);
create_insn (0X80317B7C);
create_insn (x=0X80317B94);
op_hex (x, 1);
make_array (0X80317BEC, 0X4);
set_cmt (0X80317D19, "jump table for switch statement", 0);
create_byte (0X80317D19);
make_array (0X80317D19, 0X14);
create_qword (x=0X80317E60);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_qword (x=0X80317E68);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_qword (x=0X80317E70);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_qword (x=0X80317E78);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
MakeStruct (0X80317E80, "KInitialPageAllocator");
set_name (0X80317E80, "g_InitialPageAllocator");
make_array (0X80317E90, 0X10);
create_qword (x=0X80317EA0);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
set_name (0X80317EA0, "KInitialPageAllocator::vtable");
create_qword (x=0X80317EA8);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_qword (0X80317EB0);
}
static Functions_0(void) {
add_func (0X80315000,0X80315094);
set_func_flags(0X80315000,0x400);
SetType(0X80315000, "void __fastcall kernelldr_main(_QWORD kernel_base_address, KernelMap *kernel_map, _QWORD ini1_base_address);");
set_frame_size(0X80315000, 0X20, 0, 0);
define_local_var(0X80315000, 0X80315094, "[bp-0X10]", "ini1_base_address");
add_func (0X80315094,0X803150C0);
set_func_flags(0X80315094,0x400);
SetType(0X80315094, "__int64 __fastcall kernelldr_save_tpidr_registers(_QWORD *a1);");
set_frame_size(0X80315094, 0, 0, 0);
add_func (0X803150C0,0X803150D4);
set_func_flags(0X803150C0,0x400);
add_func (0X80315800,0X80315804);
set_func_flags(0X80315800,0x401);
SetType(0X80315800, "void __fastcall synch_sp0_exception();");
add_func (0X80315880,0X80315884);
set_func_flags(0X80315880,0x401);
add_func (0X80315900,0X80315904);
set_func_flags(0X80315900,0x401);
add_func (0X80315980,0X80315984);
set_func_flags(0X80315980,0x401);
add_func (0X80315A00,0X80315A04);
set_func_flags(0X80315A00,0x480);
add_func (0X80315A80,0X80315A84);
set_func_flags(0X80315A80,0x401);
add_func (0X80315B00,0X80315B04);
set_func_flags(0X80315B00,0x401);
add_func (0X80315B80,0X80315B84);
set_func_flags(0X80315B80,0x401);
add_func (0X80315C00,0X80315C04);
set_func_flags(0X80315C00,0x401);
add_func (0X80315C80,0X80315C84);
set_func_flags(0X80315C80,0x401);
add_func (0X80315D00,0X80315D04);
set_func_flags(0X80315D00,0x401);
add_func (0X80315D80,0X80315D84);
set_func_flags(0X80315D80,0x401);
add_func (0X80315E00,0X80315E04);
set_func_flags(0X80315E00,0x401);
add_func (0X80315E80,0X80315E84);
set_func_flags(0X80315E80,0x401);
add_func (0X80315F00,0X80315F04);
set_func_flags(0X80315F00,0x401);
add_func (0X80315F80,0X80315F84);
set_func_flags(0X80315F80,0x401);
add_func (0X80315F84,0X80315FB4);
set_func_flags(0X80315F84,0x400);
add_func (0X80315FD8,0X80316038);
set_func_flags(0X80315FD8,0x410);
SetType(0X80315FD8, "__int64 __fastcall kernelldr_relocate_kernel_physically(_QWORD *p_kernel_base, KernelMap **p_kernel_map);");
set_frame_size(0X80315FD8, 0X20, 16, 0);
add_func (0X80316038,0X803163FC);
set_func_flags(0X80316038,0x410);
SetType(0X80316038, "void __cdecl kernelldr_map_initial_identity_mapping(KInitialPageTable *ttbr1_page_table, _QWORD kernel_base, _QWORD kernel_size, _QWORD page_tables_base, _QWORD page_tables_size, KInitialPageAllocator *allocator);");
set_frame_size(0X80316038, 0XC0, 16, 0);
define_local_var(0X80316038, 0X803163FC, "[bp-0XC0]", "attr");
define_local_var(0X80316038, 0X803163FC, "[bp-0X50]", "ttbr0_page_table");
add_func (0X803163FC,0X80316900);
set_func_flags(0X803163FC,0x410);
SetType(0X803163FC, "void __fastcall KInitialPageTable__Map(KInitialPageTable *this, _QWORD address, _QWORD size, _QWORD phys_address, const _QWORD *attribute, KInitialPageAllocator *allocator);");
set_frame_size(0X803163FC, 0X60, 16, 0);
add_func (0X80316900,0X8031696C);
set_func_flags(0X80316900,0x400);
SetType(0X80316900, "_QWORD __cdecl kernelldr_generate_random_range(_QWORD, _QWORD);");
set_frame_size(0X80316900, 0X20, 0, 0);
add_func (0X8031696C,0X803169B4);
set_func_flags(0X8031696C,0x400);
SetType(0X8031696C, "bool __fastcall kernelldr_should_reserve_additional_kernel_data();");
set_frame_size(0X8031696C, 0X10, 0, 0);
add_func (0X803169B4,0X80316A7C);
set_func_flags(0X803169B4,0x400);
SetType(0X803169B4, "_QWORD __cdecl kernelldr_get_adjusted_kernel_physical_base(_QWORD b);");
set_frame_size(0X803169B4, 0X20, 0, 0);
add_func (0X80316A7C,0X80316AC4);
set_func_flags(0X80316A7C,0x410);
SetType(0X80316A7C, "void __cdecl kernelldr_libc_init_array();");
set_frame_size(0X80316A7C, 0X10, 16, 0);
add_func (0X80316AC4,0X80316E28);
set_func_flags(0X80316AC4,0x410);
SetType(0X80316AC4, "_QWORD __fastcall kernelldr_load_kernel(_QWORD kernel_base_address, KernelMap *kernel_map, _QWORD ini1_base_address);");
set_frame_size(0X80316AC4, 0XA0, 16, 0);
define_local_var(0X80316AC4, 0X80316E28, "[bp-0XA0]", "bss_offset");
define_local_var(0X80316AC4, 0X80316E28, "[bp-0X98]", "dynamic_end_offset");
define_local_var(0X80316AC4, 0X80316E28, "[bp-0X90]", "init_array_end_offset");
define_local_var(0X80316AC4, 0X80316E28, "[bp-0X88]", "init_array_offset");
define_local_var(0X80316AC4, 0X80316E28, "[bp-0X80]", "ttbr1_page_table");
define_local_var(0X80316AC4, 0X80316E28, "[bp-0X68]", "a2");
define_local_var(0X80316AC4, 0X80316E28, "[bp-0X60]", "a1");
define_local_var(0X80316AC4, 0X80316E28, "[bp-0X58]", "attribute");
add_func (0X80316E28,0X803174A0);
set_func_flags(0X80316E28,0x400);
SetType(0X80316E28, "void __cdecl KInitialPageTable__ReprotectToReadOnly(KInitialPageTable *this, _QWORD address, _QWORD size);");
set_frame_size(0X80316E28, 0X60, 0, 0);
add_func (0X803174A0,0X803174B0);
set_func_flags(0X803174A0,0x400);
add_func (0X803174B0,0X803174F0);
set_func_flags(0X803174B0,0x410);
SetType(0X803174B0, "__int64 __fastcall KInitialPageAllocator__Allocate(KInitialPageAllocator *this);");
set_frame_size(0X803174B0, 0X10, 16, 0);
add_func (0X803174F0,0X803174F4);
set_func_flags(0X803174F0,0x440);
add_func (0X803174F4,0X8031764C);
set_func_flags(0X803174F4,0x400);
SetType(0X803174F4, "__int64 __cdecl kernelldr_apply_relocations(_QWORD base_address, _DWORD *dynamic);");
add_func (0X80317650,0X803177B8);
set_func_flags(0X80317650,0x410);
set_frame_size(0X80317650, 0X10, 16, 0);
add_func (0X803177B8,0X80317888);
set_func_flags(0X803177B8,0x400);
add_func (0X80317888,0X80317BEC);
set_func_flags(0X80317888,0x400);
}
//------------------------------------------------------------------------
// Information about functions
static Functions(void) {
Functions_0();
}
//------------------------------------------------------------------------
// Information about segment registers
static SegRegs(void) {
split_sreg_range(0X80315000,"T",0,3);
split_sreg_range(0X80317BEC,"T",0,3);
split_sreg_range(0X80317BF0,"T",0,3);
split_sreg_range(0X80317C98,"T",0,3);
split_sreg_range(0X80317CD0,"T",0,3);
split_sreg_range(0X80317D18,"T",0,3);
split_sreg_range(0X80317D19,"T",0,3);
split_sreg_range(0X80317D30,"T",0,3);
split_sreg_range(0X80317E00,"T",0,3);
split_sreg_range(0X80317E80,"T",0,3);
split_sreg_range(0X80317EB0,"T",0,3);
split_sreg_range(0X80319008,"T",0,3);
split_sreg_range(0X80315000,"DS",0,3);
split_sreg_range(0X80317BEC,"DS",0,3);
split_sreg_range(0X80317BF0,"DS",0,3);
split_sreg_range(0X80317C98,"DS",0,3);
split_sreg_range(0X80317CD0,"DS",0,3);
split_sreg_range(0X80317D18,"DS",0,3);
split_sreg_range(0X80317D19,"DS",0,3);
split_sreg_range(0X80317D30,"DS",0,3);
split_sreg_range(0X80317E00,"DS",0,3);
split_sreg_range(0X80317E80,"DS",0,3);
split_sreg_range(0X80317EB0,"DS",0,3);
split_sreg_range(0X80319008,"DS",0,3);
}
//------------------------------------------------------------------------
// Information about all patched bytes:
static Patches(void) {
}
//------------------------------------------------------------------------
// Call all byte feature functions:
static Bytes(void) {
Bytes_0();
end_type_updating(UTP_STRUCT);
}
// End of file.
# Copyright 2017 Reswitched Team
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or
# without fee is hereby granted, provided that the above copyright notice and this permission
# notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
# OR PERFORMANCE OF THIS SOFTWARE.
# nxo64.py: IDA loader (and library for reading nso/nro files)
import gzip, math, os, re, struct, sys
from struct import unpack as up, pack as pk
from io import BytesIO
from cStringIO import StringIO
(DT_NULL, DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA, DT_RELASZ,
DT_RELAENT, DT_STRSZ, DT_SYMENT, DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, DT_SYMBOLIC, DT_REL,
DT_RELSZ, DT_RELENT, DT_PLTREL, DT_DEBUG, DT_TEXTREL, DT_JMPREL, DT_BIND_NOW, DT_INIT_ARRAY,
DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, DT_FLAGS) = xrange(31)
DT_GNU_HASH = 0x6ffffef5
DT_VERSYM = 0x6ffffff0
DT_RELACOUNT = 0x6ffffff9
DT_RELCOUNT = 0x6ffffffa
DT_FLAGS_1 = 0x6ffffffb
DT_VERDEF = 0x6ffffffc
DT_VERDEFNUM = 0x6ffffffd
STT_NOTYPE = 0
STT_OBJECT = 1
STT_FUNC = 2
STT_SECTION = 3
STB_LOCAL = 0
STB_GLOBAL = 1
STB_WEAK = 2
R_ARM_ABS32 = 2
R_ARM_TLS_DESC = 13
R_ARM_GLOB_DAT = 21
R_ARM_JUMP_SLOT = 22
R_ARM_RELATIVE = 23
R_AARCH64_ABS64 = 257
R_AARCH64_GLOB_DAT = 1025
R_AARCH64_JUMP_SLOT = 1026
R_AARCH64_RELATIVE = 1027
R_AARCH64_TLSDESC = 1031
MULTIPLE_DTS = set([DT_NEEDED])
class Range(object):
def __init__(self, start, size):
self.start = start
self.size = size
self.end = start+size
self._inclend = start+size-1
def overlaps(self, other):
return self.start <= other._inclend and other.start <= self._inclend
def includes(self, other):
return other.start >= self.start and other._inclend <= self._inclend
def __repr__(self):
return 'Range(0x%X -> 0x%X)' % (self.start, self.end)
class Segment(object):
def __init__(self, r, name, kind):
self.range = r
self.name = name
self.kind = kind
self.sections = []
def add_section(self, s):
for i in self.sections:
assert not i.range.overlaps(s.range), '%r overlaps %r' % (s, i)
self.sections.append(s)
class Section(object):
def __init__(self, r, name):
self.range = r
self.name = name
def __repr__(self):
return 'Section(%r, %r)' % (self.range, self.name)
def suffixed_name(name, suffix):
if suffix == 0:
return name
return '%s.%d' % (name, suffix)
class SegmentBuilder(object):
def __init__(self):
self.segments = []
def add_segment(self, start, size, name, kind):
r = Range(start, size)
for i in self.segments:
assert not r.overlaps(i.range)
self.segments.append(Segment(r, name, kind))
def add_section(self, name, start, end=None, size=None):
assert end is None or size is None
if size is None:
size = end-start
assert size > 0
r = Range(start, size)
for i in self.segments:
if i.range.includes(r):
i.add_section(Section(r, name))
return
assert False, "no containing segment for %r" % (name,)
def flatten(self):
self.segments.sort(key=lambda s: s.range.start)
parts = []
for segment in self.segments:
suffix = 0
segment.sections.sort(key=lambda s: s.range.start)
pos = segment.range.start
for section in segment.sections:
if pos < section.range.start:
parts.append((pos, section.range.start, suffixed_name(segment.name, suffix), segment.kind))
suffix += 1
pos = section.range.start
parts.append((section.range.start, section.range.end, section.name, segment.kind))
pos = section.range.end
if pos < segment.range.end:
parts.append((pos, segment.range.end, suffixed_name(segment.name, suffix), segment.kind))
suffix += 1
pos = segment.range.end
return parts
class ElfSym(object):
def __init__(self, name, info, other, shndx, value, size):
self.name = name
self.shndx = shndx
self.value = value
self.size = size
self.vis = other & 3
self.type = info & 0xF
self.bind = info >> 4
def __repr__(self):
return 'Sym(name=%r, shndx=0x%X, value=0x%X, size=0x%X, vis=%r, type=%r, bind=%r)' % (
self.name, self.shndx, self.value, self.size, self.vis, self.type, self.bind)
class KernelLdr80b(object):
def __init__(self, fileobj):
f = BinFile(fileobj)
b = 0x80315000
self.textoff = 0
self.textsize = 0x2BEC - 0
self.rodataoff = 0x2BEC
self.rodatasize = 0x2D30 - 0x2BEC
#self.dataoff = 0x18D8 # ???
self.dataoff = 0x2D30
self.datasize = 0x2EB0 - 0x2D30
flatsize = self.dataoff + self.datasize
self.binfile = f
self.dynamicoff = 0x2D30
self.bssoff = 0x2EB0
self.bssend = 0x3EB0
#self.gotoff = 0x18A0
self.gotend = 0x2E80
self.datasize = self.bssoff - self.dataoff
self.bsssize = self.bssend - self.bssoff
self.segment_builder = builder = SegmentBuilder()
for off,sz,name,kind in [
(self.textoff, self.textsize, ".text", "CODE"),
(self.rodataoff, self.rodatasize, ".rodata", "CONST"),
(self.dataoff, self.datasize, ".data", "DATA"),
(self.bssoff, self.bsssize, ".bss", "BSS"),
]:
builder.add_segment(off, sz, name, kind)
# read dynamic
self.armv7 = False#(f.read_from('Q', self.dynamicoff) > 0xFFFFFFFF or f.read_from('Q', self.dynamicoff+0x10) > 0xFFFFFFFF)
self.offsize = 4 if self.armv7 else 8
f.seek(self.dynamicoff)
self.dynamic = dynamic = {}
for i in MULTIPLE_DTS:
dynamic[i] = []
for i in xrange((flatsize - self.dynamicoff) / 0x10):
tag, val = f.read('II' if self.armv7 else 'QQ')
if tag == DT_NULL:
break
if tag in MULTIPLE_DTS:
dynamic[tag].append(val)
else:
dynamic[tag] = val
dynamicend = f.tell()
builder.add_section('.dynamic', self.dynamicoff, dynamicend)
# read .dynstr
if DT_STRTAB in dynamic and DT_STRSZ in dynamic:
f.seek(dynamic[DT_STRTAB])
self.dynstr = f.read(dynamic[DT_STRSZ])
else:
self.dynstr = '\0'
print 'warning: no dynstr'
for startkey, szkey, name in [
(DT_STRTAB, DT_STRSZ, '.dynstr'),
(DT_INIT_ARRAY, DT_INIT_ARRAYSZ, '.init_array'),
(DT_FINI_ARRAY, DT_FINI_ARRAYSZ, '.fini_array'),
(DT_RELA, DT_RELASZ, '.rela.dyn'),
(DT_REL, DT_RELSZ, '.rel.dyn'),
(DT_JMPREL, DT_PLTRELSZ, ('.rel.plt' if self.armv7 else '.rela.plt')),
]:
if startkey in dynamic and szkey in dynamic:
builder.add_section(name, dynamic[startkey], size=dynamic[szkey])
self.needed = [self.get_dynstr(i) for i in self.dynamic[DT_NEEDED]]
# load .dynsym
self.symbols = symbols = []
f.seek(dynamic[DT_SYMTAB])
while True:
if dynamic[DT_SYMTAB] < dynamic[DT_STRTAB] and f.tell() >= dynamic[DT_STRTAB]:
break
if self.armv7:
st_name, st_value, st_size, st_info, st_other, st_shndx = f.read('IIIBBH')
else:
st_name, st_info, st_other, st_shndx, st_value, st_size = f.read('IBBHQQ')
if st_name > len(self.dynstr):
break
symbols.append(ElfSym(self.get_dynstr(st_name), st_info, st_other, st_shndx, st_value, st_size))
builder.add_section('.dynsym', dynamic[DT_SYMTAB], end=f.tell())
self.plt_entries = []
self.relocations = []
locations = set()
if DT_REL in dynamic:
locations |= self.process_relocations(f, symbols, dynamic[DT_REL], dynamic[DT_RELSZ])
if DT_RELA in dynamic:
locations |= self.process_relocations(f, symbols, dynamic[DT_RELA], dynamic[DT_RELASZ])
if DT_JMPREL in dynamic:
# Note: 5.0 kernel doesn't have it
pltlocations = self.process_relocations(f, symbols, dynamic[DT_JMPREL], dynamic[DT_PLTRELSZ])
locations |= pltlocations
plt_got_start = min(pltlocations)
plt_got_end = max(pltlocations) + self.offsize
if DT_PLTGOT in dynamic:
builder.add_section('.got.plt', dynamic[DT_PLTGOT], end=plt_got_end)
if not self.armv7:
f.seek(0)
text = f.read(self.textsize)
last = 12
while True:
pos = text.find(struct.pack('<I', 0xD61F0220), last)
if pos == -1: break
last = pos+1
if (pos % 4) != 0: continue
off = pos - 12
a, b, c, d = struct.unpack_from('<IIII', text, off)
if d == 0xD61F0220 and (a & 0x9f00001f) == 0x90000010 and (b & 0xffe003ff) == 0xf9400211:
base = off & ~0xFFF
immhi = (a >> 5) & 0x7ffff
immlo = (a >> 29) & 3
paddr = base + ((immlo << 12) | (immhi << 14))
poff = ((b >> 10) & 0xfff) << 3
target = paddr + poff
if plt_got_start <= target < plt_got_end:
self.plt_entries.append((off, target))
builder.add_section('.plt', min(self.plt_entries)[0], end=max(self.plt_entries)[0] + 0x10)
# try to find the ".got" which should follow the ".got.plt"
good = False
got_end = plt_got_end + self.offsize
while got_end in locations and (DT_INIT_ARRAY not in dynamic or got_end < dynamic[DT_INIT_ARRAY]):
good = True
got_end += self.offsize
if good:
builder.add_section('.got', plt_got_end, end=got_end)
else:
builder.add_section('.got', dynamicend, self.gotend)
self.sections = []
for start, end, name, kind in builder.flatten():
self.sections.append((start, end, name, kind))
def process_relocations(self, f, symbols, offset, size):
locations = set()
f.seek(offset)
relocsize = 8 if self.armv7 else 0x18
for i in xrange(size / relocsize):
# NOTE: currently assumes all armv7 relocs have no addends,
# and all 64-bit ones do.
if self.armv7:
offset, info = f.read('II')
addend = None
r_type = info & 0xff
r_sym = info >> 8
else:
offset, info, addend = f.read('QQq')
r_type = info & 0xffffffff
r_sym = info >> 32
sym = symbols[r_sym] if r_sym != 0 else None
if r_type != R_AARCH64_TLSDESC and r_type != R_ARM_TLS_DESC:
locations.add(offset)
self.relocations.append((offset, r_type, sym, addend))
return locations
def get_dynstr(self, o):
return self.dynstr[o:self.dynstr.index('\0', o)]
class NxoException(Exception):
pass
def load_nxo(fileobj):
fileobj.seek(0)
return KernelLdr80b(fileobj)
try:
import idaapi
import idc
except ImportError:
pass
else:
# IDA specific code
def accept_file(li, n):
if not isinstance(n, (int,long)) or n == 0:
li.seek(0)
if li.read(4) == '\x12\x00\x00\x10':
return 'NX KernelLoader'
return 0
def ida_make_offset(f, ea):
if f.armv7:
idc.MakeDword(ea)
else:
idc.MakeQword(ea)
idc.OpOff(ea, 0, 0)
def find_bl_targets(text_start, text_end):
targets = set()
for pc in range(text_start, text_end, 4):
d = Dword(pc)
if (d & 0xfc000000) == 0x94000000:
imm = d & 0x3ffffff
if imm & 0x2000000:
imm |= ~0x1ffffff
if 0 <= imm <= 2:
continue
target = pc + imm * 4
if target >= text_start and target < text_end:
targets.add(target)
return targets
def load_file(li, neflags, format):
idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL)
f = load_nxo(li)
if f.armv7:
idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT)
else:
idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_64BIT)
idc.SetCharPrm(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3)
idaapi.set_compiler_id(idaapi.COMP_GNU)
idaapi.add_til2('gnulnx_arm' if f.armv7 else 'gnulnx_arm64', 1)
#loadbase = 0x60000000 if f.armv7 else 0x7100000000
loadbase = 0x80315000
#loadbase = 0xFFFFFF8000060000
f.binfile.seek(0)
as_string = f.binfile.read(f.bssoff)
idaapi.mem2base(as_string, loadbase)
for start, end, name, kind in f.sections:
if name.startswith('.got'):
kind = 'CONST'
idaapi.add_segm(0, loadbase+start, loadbase+end, name, kind)
segm = idaapi.get_segm_by_name(name)
if kind == 'CONST':
segm.perm = idaapi.SEGPERM_READ
elif kind == 'CODE':
segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_EXEC
elif kind == 'DATA':
segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
elif kind == 'BSS':
segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
idaapi.update_segm(segm)
idaapi.set_segm_addressing(segm, 1 if f.armv7 else 2)
# do imports
# TODO: can we make imports show up in "Imports" window?
undef_count = 0
for s in f.symbols:
if not s.shndx and s.name:
undef_count += 1
last_ea = max(loadbase + end for start, end, name, kind in f.sections)
undef_entry_size = 8
undef_ea = ((last_ea + 0xFFF) & ~0xFFF) + undef_entry_size # plus 8 so we don't end up on the "end" symbol
idaapi.add_segm(0, undef_ea, undef_ea+undef_count*undef_entry_size, "UNDEF", "XTRN")
segm = idaapi.get_segm_by_name("UNDEF")
segm.type = idaapi.SEG_XTRN
idaapi.update_segm(segm)
for i,s in enumerate(f.symbols):
if not s.shndx and s.name:
idc.MakeQword(undef_ea)
idaapi.do_name_anyway(undef_ea, s.name)
s.resolved = undef_ea
undef_ea += undef_entry_size
elif i != 0:
assert s.shndx
s.resolved = loadbase + s.value
if s.name:
if s.type == STT_FUNC:
print hex(s.resolved), s.name
idaapi.add_entry(s.resolved, s.resolved, s.name, 0)
else:
idaapi.do_name_anyway(s.resolved, s.name)
else:
# NULL symbol
s.resolved = 0
funcs = set()
for s in f.symbols:
if s.name and s.shndx and s.value:
if s.type == STT_FUNC:
funcs.add(loadbase+s.value)
got_name_lookup = {}
for offset, r_type, sym, addend in f.relocations:
target = offset + loadbase
if r_type in (R_ARM_GLOB_DAT, R_ARM_JUMP_SLOT, R_ARM_ABS32):
if not sym:
print 'error: relocation at %X failed' % target
else:
idaapi.put_long(target, sym.resolved)
elif r_type == R_ARM_RELATIVE:
idaapi.put_long(target, idaapi.get_long(target) + loadbase)
elif r_type in (R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT, R_AARCH64_ABS64):
idaapi.put_qword(target, sym.resolved + addend)
if addend == 0:
got_name_lookup[offset] = sym.name
elif r_type == R_AARCH64_RELATIVE:
idaapi.put_qword(target, loadbase + addend)
if addend < f.textsize:
funcs.add(loadbase + addend)
else:
print 'TODO r_type %d' % (r_type,)
ida_make_offset(f, target)
for func, target in f.plt_entries:
if target in got_name_lookup:
addr = loadbase + func
funcs.add(addr)
idaapi.do_name_anyway(addr, got_name_lookup[target])
funcs |= find_bl_targets(loadbase, loadbase+f.textsize)
for addr in sorted(funcs, reverse=True):
idc.AutoMark(addr, AU_CODE)
idc.AutoMark(addr, AU_PROC)
return 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.