diff options
Diffstat (limited to 'src/tools/box32stack.c')
| -rw-r--r-- | src/tools/box32stack.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/tools/box32stack.c b/src/tools/box32stack.c new file mode 100644 index 00000000..441b27ab --- /dev/null +++ b/src/tools/box32stack.c @@ -0,0 +1,137 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/mman.h> + +#include "box64stack.h" +#include "box64context.h" +#include "elfloader.h" +#include "debug.h" +#include "emu/x64emu_private.h" +#include "emu/x64run_private.h" +#include "auxval.h" +#include "custommem.h" +#include "box32.h" + +static void PushString32(x64emu_t *emu, const char* s) +{ + int sz = strlen(s) + 1; + // round to 4 bytes boundary + R_ESP -= sz; + memcpy(from_ptrv(R_ESP), s, sz); +} + +static void Push32_32(x64emu_t *emu, uint32_t v) +{ + R_ESP -= 4; + *((uint32_t*)from_ptr(R_ESP)) = v; +} + + +EXPORTDYN +void SetupInitialStack32(x64emu_t *emu) +{ + // start with 0 + Push32_32(emu, 0); + // push program executed + PushString32(emu, emu->context->argv[0]); + uintptr_t p_arg0 = from_ptr(R_ESP); + // push envs + uintptr_t p_envv[emu->context->envc]; + for (int i=emu->context->envc-1; i>=0; --i) { + PushString32(emu, emu->context->envv[i]); + p_envv[i] = from_ptr(R_ESP); + } + // push args, also, free the argv[] string and point to the one in the main stack + uintptr_t p_argv[emu->context->argc]; + for (int i=emu->context->argc-1; i>=0; --i) { + PushString32(emu, emu->context->argv[i]); + p_argv[i] = R_ESP; + free(emu->context->argv[i]); + emu->context->argv[i] = (char*)p_argv[i]; + } + // align + uintptr_t tmp = from_ptr(R_ESP)&~(emu->context->stackalign-1); + memset((void*)tmp, 0, from_ptr(R_ESP)-tmp); + R_ESP=to_ptr(tmp); + + // push some AuxVector stuffs + PushString32(emu, "i686"); + uintptr_t p_i686 = from_ptr(R_ESP); + uintptr_t p_random = real_getauxval(25); + if(!p_random) { + for (int i=0; i<4; ++i) + Push32_32(emu, random()); + p_random = from_ptr(R_ESP); + } + // align + tmp = (R_ESP)&~(emu->context->stackalign-1); + memset((void*)tmp, 0, from_ptr(R_ESP)-tmp); + R_ESP=tmp; + + // push the AuxVector themselves + /* + 00: 00000000 + 03: 08048034 + 04: 00000020 + 05: 0000000b + 06: 00001000 + 07: f7fc0000 + 08: 00000000 + 09: 08049060 + 11: 000003e8 + 12: 000003e8 + 13: 000003e8 + 14: 000003e8 + 15: ffd8aa5b/i686 + 16: bfebfbff + 17: 00000064 + 23: 00000000 + 25: ffd8aa4b + 26: 00000000 + 31: ffd8bfeb/./testAuxVec + 32: f7fbfb40 + 33: f7fbf000 + */ + Push32_32(emu, 0); Push32_32(emu, 0); //AT_NULL(0)=0 + //Push32_32(emu, ); Push32_32(emu, 3); //AT_PHDR(3)=address of the PH of the executable + //Push32_32(emu, ); Push32_32(emu, 4); //AT_PHENT(4)=size of PH entry + //Push32_32(emu, ); Push32_32(emu, 5); //AT_PHNUM(5)=number of elf headers + Push32_32(emu, box64_pagesize); Push32_32(emu, 6); //AT_PAGESZ(6) + //Push32_32(emu, real_getauxval(7)); Push32_32(emu, 7); //AT_BASE(7)=ld-2.27.so start (in memory) + Push32_32(emu, 0); Push32_32(emu, 8); //AT_FLAGS(8)=0 + Push32_32(emu, R_EIP); Push32_32(emu, 9); //AT_ENTRY(9)=entrypoint + Push32_32(emu, from_ulong(real_getauxval(11))); Push32_32(emu, 11); //AT_UID(11) + Push32_32(emu, from_ulong(real_getauxval(12))); Push32_32(emu, 12); //AT_EUID(12) + Push32_32(emu, from_ulong(real_getauxval(13))); Push32_32(emu, 13); //AT_GID(13) + Push32_32(emu, from_ulong(real_getauxval(14))); Push32_32(emu, 14); //AT_EGID(14) + Push32_32(emu, p_i686); Push32_32(emu, 15); //AT_PLATFORM(15)=&"i686" + // Push HWCAP: + // FPU: 1<<0 ; VME: 1<<1 ; DE : 1<<2 ; PSE: 1<<3 ; TSC: 1<<4 ; MSR: 1<<5 ; PAE: 1<<6 ; MCE: 1<<7 + // CX8: 1<<8 ; APIC:1<<9 ; SEP: 1<<11; MTRR:1<<12; PGE: 1<<13; MCA: 1<<14; CMOV:1<<15 + // FCMOV:1<<16; MMX: 1<<23 + // OSFXR:1<<24; XMM: 1<<25;XMM2: 1<<26; AMD3D:1<<31 + Push32_32(emu, (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<8) | (1<<15) | (1<<16) | (1<<23) | (1<<25) | (1<<26)); + Push32_32(emu, 16); //AT_HWCAP(16)=... + //Push32_32(emu, sysconf(_SC_CLK_TCK)); Push32_32(emu, 17); //AT_CLKTCK(17)=times() frequency + Push32_32(emu, from_ulong(real_getauxval(23))); Push32_32(emu, 23); //AT_SECURE(23) + Push32_32(emu, p_random); Push32_32(emu, 25); //AT_RANDOM(25)=p_random + Push32_32(emu, 0); Push32_32(emu, 26); //AT_HWCAP2(26)=0 + Push32_32(emu, p_arg0); Push32_32(emu, 31); //AT_EXECFN(31)=p_arg0 + Push32_32(emu, emu->context->vsyscall); Push32_32(emu, 32); //AT_SYSINFO(32)=vsyscall + //Push32_32(emu, ); Push32_32(emu, 33); //AT_SYSINFO_EHDR(33)=address of vDSO + if(!emu->context->auxval_start) // store auxval start if needed + emu->context->auxval_start = (uintptr_t*)from_ptr(R_ESP); + + // push nil / envs / nil / args / argc + Push32_32(emu, 0); + for (int i=emu->context->envc-1; i>=0; --i) + Push32_32(emu, to_ptr(p_envv[i])); + emu->context->envv32 = R_ESP; + Push32_32(emu, 0); + for (int i=emu->context->argc-1; i>=0; --i) + Push32_32(emu, to_ptr(p_argv[i])); + emu->context->argv32 = R_ESP; + Push32_32(emu, emu->context->argc); +} |