Skip to content

Instantly share code, notes, and snippets.

@schellingb
Last active January 17, 2021 14:10
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 schellingb/a40bdd2b4613b2843af8cc21be4a1d5b to your computer and use it in GitHub Desktop.
Save schellingb/a40bdd2b4613b2843af8cc21be4a1d5b to your computer and use it in GitHub Desktop.
DOSBox - risc_x86 gen_runcode without inline assembly
static BlockReturn gen_runcodeInit(Bit8u *code);
static BlockReturn (*gen_runcode)(Bit8u *code) = gen_runcodeInit;
static BlockReturn gen_runcodeInit(Bit8u *code) {
Bit8u* oldpos = cache.pos;
cache.pos = &cache_code_link_blocks[128];
gen_runcode = (BlockReturn(*)(Bit8u*))cache.pos;
#if 1
cache_addb(0x53); // push ebx
cache_addb(0x57); // push edi
cache_addb(0x56); // push esi
cache_addb(0xb9); cache_addd(FMASK_TEST); // mov ecx,FMASK_TEST
cache_addb(0x8b); cache_addb(0x44); cache_addb(0x24); cache_addb(0x10); // mov eax,DWORD PTR [esp+0x10]
cache_addb(0x23); cache_addb(0x0d); cache_addd((Bit32u)&reg_flags); // and ecx,DWORD PTR [reg_flags]
cache_addb(0x55); // push ebp
cache_addb(0x68); Bit8u *ret_addr = cache.pos; cache_addd(0); // push return_address
cache_addb(0x51); // push ecx
cache_addb(0xff); cache_addb(0xe0); // jmp eax
*(Bit32u*)ret_addr = (Bit32u)(cache.pos); // write actual return_address
/* Restore the flags */
/* return here with flags in ecx */
cache_addb(0x5d); // pop ebp
cache_addb(0xBA); cache_addd(~FMASK_TEST); // mov edx,~FMASK_TEST
cache_addb(0x81); cache_addb(0xE1); cache_addd(FMASK_TEST); // and ecx,FMASK_TEST
cache_addb(0x23); cache_addb(0x15); cache_addd((Bit32u)&reg_flags); // and edx,DWORD PTR [reg_flags]
cache_addb(0x09); cache_addb(0xD1); // or ecx,edx
cache_addb(0x89); cache_addb(0x0D); cache_addd((Bit32u)&reg_flags); // mov DWORD PTR [reg_flags],ecx
cache_addb(0x5E); // pop esi
cache_addb(0x5F); // pop edi
cache_addb(0x5B); // pop ebx
cache_addb(0xC3); // ret
#elif 1
cache_addb(0xA1); cache_addd((Bit32u)&reg_flags); //mov eax,ds:&reg_flags
cache_addb(0x57); // push edi
cache_addb(0x56); // push esi
cache_addb(0x25); cache_addd(FMASK_TEST); // and eax,FMASK_TEST
cache_addb(0x53); // push ebx
cache_addb(0x8B); cache_addb(0x4C); cache_addb(0x24); cache_addb(0x10); // mov ecx,DWORD PTR [esp+0x10]
cache_addb(0x55); // push ebp
cache_addb(0x68); Bit8u *ret_addr = cache.pos; cache_addd(0); // push return_address
cache_addb(0x50); // push eax
cache_addb(0xFF); cache_addb(0xE1); // jmp ecx
*(Bit32u*)ret_addr = (Bit32u)(cache.pos); // write actual return_address
/* Restore the flags */
/* return here with flags in ecx */
cache_addb(0x5D); // pop ebp
cache_addb(0x8B); cache_addb(0x15); cache_addd((Bit32u)&reg_flags); // mov edx,DWORD PTR ds:&reg_flags
cache_addb(0x81); cache_addb(0xE1); cache_addd(FMASK_TEST); // and ecx,FMASK_TEST
cache_addb(0x5B); // pop ebx
cache_addb(0x5E); // pop esi
cache_addb(0x5F); // pop edi
cache_addb(0x81); cache_addb(0xE2); cache_addd(~FMASK_TEST); // and edx,~FMASK_TEST
cache_addb(0x09); cache_addb(0xCA); // or edx,ecx
cache_addb(0x89); cache_addb(0x15); cache_addd((Bit32u)&reg_flags); // mov DWORD PTR ds:&reg_flags,edx
cache_addb(0xC3); // ret
#else
cache_addb(0x55); // push ebp
cache_addb(0x8B); cache_addb(0xEC); // mov ebp,esp
cache_addb(0x51); // push ecx
cache_addb(0x53); // push ebx
cache_addb(0x56); // push esi
cache_addb(0x57); // push edi
cache_addb(0x8B); cache_addb(0x45); cache_addb(0x08); // mov eax,[code]
cache_addb(0x53); // push ebx
cache_addb(0x55); // push ebp
cache_addb(0x56); // push esi
cache_addb(0x57); // push edi
cache_addb(0x8B); cache_addb(0x1D); cache_addd((Bit32u)&reg_flags); // mov ebx,[reg_flags]
cache_addb(0x81); cache_addb(0xE3); cache_addd(FMASK_TEST); // and ebx,FMASK_TEST
cache_addb(0x68); Bit8u *ret_addr = cache.pos; cache_addd(0); // push offset(return_address)
cache_addb(0x53); // push ebx
cache_addb(0xFF); cache_addb(0xE0); // jmp eax
*(Bit32u*)ret_addr = (Bit32u)(cache.pos); // write actual return_address
/* Restore the flags */
/* return here with flags in ecx */
cache_addb(0x81); cache_addb(0x25); cache_addd((Bit32u)&reg_flags); cache_addd(~FMASK_TEST); // and dword ptr [reg_flags],~FMASK_TEST
cache_addb(0x81); cache_addb(0xE1); cache_addd(FMASK_TEST); // and ecx,FMASK_TEST
cache_addb(0x09); cache_addb(0x0D); cache_addd((Bit32u)&reg_flags); // or [reg_flags],ecx
cache_addb(0x5F); // pop edi
cache_addb(0x5E); // pop esi
cache_addb(0x5D); // pop ebp
cache_addb(0x5B); // pop ebx
cache_addb(0x89); cache_addb(0x45); cache_addb(0xFC); // mov [retval],eax
cache_addb(0x8B); cache_addb(0x45); cache_addb(0xFC); // mov eax,dword ptr [retval]
cache_addb(0x5F); // pop edi
cache_addb(0x5E); // pop esi
cache_addb(0x5B); // pop ebx
cache_addb(0x8B); cache_addb(0xE5); // mov esp,ebp
cache_addb(0x5D); // pop ebp
cache_addb(0xC3); // ret
#endif
cache.pos = oldpos;
return gen_runcode(code);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment