Skip to content

Instantly share code, notes, and snippets.

@sck
Created August 10, 2013 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sck/6202272 to your computer and use it in GitHub Desktop.
Save sck/6202272 to your computer and use it in GitHub Desktop.
A little uneccessary function that detects PIC vs no-pic from looking at its own opcodes generated by the compiler. Will only work with some compilers.
constexpr uchar I_REX_B_41 = 0x41;
constexpr uchar I_REX_W_48 = 0x48;
constexpr uchar I_REX_WXB_4b = 0x4b;
constexpr uchar I_REX_WRXB_4f = 0x4f;
// INTEL: Opcodes
constexpr uchar I_PUSH_BP_55 = 0x55;
constexpr uchar I_LEA_8d = 0x8d;
constexpr uchar I_MOV_r8_rm8_8a = 0x8a;
constexpr uchar I_MOV_r64_r64_8b = 0x8b;
constexpr uchar I_LEA_bf = 0xbf;
constexpr uchar I_JMP_e9 = 0xe9;
constexpr uchar I_CALL_e8 = 0xe8;
constexpr uchar I_XOR_30 = 0x30;
// Intel: Mod/RM
constexpr uchar I_RM_BITS_07 = 0x07;
constexpr uchar I_MOD_BITS_c0 = 128 + 64;
constexpr uchar I_MOD_SDWORD_RAX_SDWORD_AL_80 = 0x80;
constexpr uchar I_MOD_SDWORD_RDI_SDWORD_BH_bf = 0xBF;
constexpr uchar I_BP_MOD_00 = 0x00;
constexpr uchar I_BP_RM_RIP_DISP32_05 = 0x05;
// ARM
constexpr uchar A_LDR_e5 = 0xe5;
constexpr uchar A_PUSH_e9 = 0xe9;
bool identify_cpu_and_pic_mode() {
uchar *start = (uchar *)identify_cpu_and_pic_mode;
uchar *p = start;
uchar c0,c1,c2;
int i = 0; p = start;
do {
c0 = *p; c1 = *(p+1); c2 = *(p+2);
// 4c 8b 3d aa 38 20 00 mov r15,QWORD PTR [rip+0x2038aa]
if ((c0 >= I_REX_W_48 && c0 <= I_REX_WRXB_4f) &&
(c1 == I_LEA_8d || c1 == I_MOV_r64_r64_8b) &&
((c2 & I_RM_BITS_07) == I_BP_RM_RIP_DISP32_05)) {
intel = true; pic_mode = true; return true;
}
p++;
} while (++i < 20);
i = 0; p = start;
do {
c0 = *p; c1 = *(p+1); c2 = *(p+2);
// 8a 88 9f 1a 40 00 mov cl,BYTE PTR [rax+0x401a9f]
// 8a 05 f9 ff ff ff mov al,BYTE PTR [rip-5]
if (c0 == I_MOV_r8_rm8_8a &&
(c1 >= I_MOD_SDWORD_RAX_SDWORD_AL_80 &&
c1 <= I_MOD_SDWORD_RDI_SDWORD_BH_bf)) {
intel = true; pic_mode = false; return true;
}
p++;
} while (++i < 20);
uchar c3; int ldr_count = 0;
i = 0; p = start;
do {
c0 = *p; c1 = *(p+1); c2 = *(p+2); c3 = *(p + 3);
// e59f0028 ldr r0, [pc, #40]
if (c3 == A_LDR_e5) { ldr_count++; }
p += 4;
i += 4;
} while (i < 100);
if (ldr_count >= 4) { arm = true; pic_mode = true; return true; }
if (ldr_count > 1) { arm = true; return true; }
cout << "Unknown CPU id: "; dump(start, 20);
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment