bitdefender / bddisasm

bddisasm is a fast, lightweight, x86/x64 instruction decoder. The project also features a fast, basic, x86/x64 instruction emulator, designed specifically to detect shellcode-like behavior.
Apache License 2.0
887 stars 115 forks source link

ShemuEmulate #44

Closed icyfox168168 closed 3 years ago

icyfox168168 commented 3 years ago
size_t _size = 0;
void* raxpoint = RelocAsm2CodeQuickEx(("mov r10d,0x99\r\n mov [rsp + 0x20],r10d\r\n mov r15,[rsp + 0x20]\r\n mov eax,0x100\r\n mov eax,0x100\r\n sub rsp,rax\r\n  inc rsp\r\n dec rsp\r\n lea r11,[rsp+0x100]\r\n mov rsp,r11\r\n ret\r\n"), &_size, __LINE__);
run_shemu((uint8_t*)raxpoint, _size, ND_CODE_64);

I want to know that the stack offset corresponding to 0x99 is 0x20, but when I look at the structure, it doesn't provide this kind of information. What should I do

icyfox168168 commented 3 years ago

run_shemu fun

void run_shemu(uint8_t* Data, size_t Size, uint8_t Def) { SHEMU_CONTEXT ctx = { 0 }; SHEMU_STATUS shs;

ctx.Shellcode = Data;

ctx.Stack = (uint8_t*)calloc(1, 0x2000);
if (ctx.Stack == NULL)
{
    printf("Failed to allocate Stack!\n");
    abort();
}

ctx.Intbuf = (uint8_t*)calloc(1, Size + 0x2000);
if (ctx.Stack == NULL)
{
    printf("Failed to allocate Intbuf!\n");
    abort();
}

ctx.ShellcodeBase = 0x200000;
ctx.ShellcodeSize = (uint32_t)Size;
ctx.StackBase = 0x100000;
ctx.StackSize = 0x2000;
ctx.Registers.RegRsp = 0x101000;
ctx.Registers.RegRcx = 0x100000; ctx.Registers.RegRdx = 0x99;
ctx.IntbufSize = (uint32_t)Size + 0x2000;

ctx.Registers.RegFlags = NDR_RFLAG_IF | 2;
ctx.Registers.RegRip = ctx.ShellcodeBase;

ctx.Segments.Cs.Selector = 0x10;
ctx.Segments.Ds.Selector = 0x28;
ctx.Segments.Es.Selector = 0x28;
ctx.Segments.Ss.Selector = 0x28;
ctx.Segments.Fs.Selector = 0x30;
ctx.Segments.Fs.Base = 0x7FFF0000;
ctx.Segments.Gs.Selector = 0x30;
ctx.Segments.Gs.Base = 0x7FFF0000;

ctx.Mode = Def;
ctx.Ring = 3;
ctx.TibBase = ctx.Mode == ND_CODE_32 ? ctx.Segments.Fs.Base : ctx.Segments.Gs.Base;
ctx.MaxInstructionsCount = 4096;
ctx.Log = &ShemuLog;
ctx.Flags = 0;
ctx.Options = SHEMU_OPT_TRACE_EMULATION;

ctx.AccessMemory = (ShemuMemAccess)&ShemuAccessMem;
shs = ShemuEmulate(&ctx);
printf("Shemu returned: 0x%08x RegRsp %08x\n", shs,ctx.Registers.RegRsp);
free(ctx.Intbuf);
free(ctx.Stack);

}

vlutas commented 3 years ago

So in essence, you want to know the value of the RSP register after the execution of the indicated code, is that correct? If so, you can simply look at the ctx.Registers.RegRsp value before and after the emulation, and you'll se exactly by how much the stack pointer has been modified.

icyfox168168 commented 3 years ago

Suppose that the parameter 0x99 points to RDX, I need to know where the offset of the 99 access is corresponding to RSP

vlutas commented 3 years ago

There is no such functionality in bdshemu. What you can do is simply iterate through the stack region (ctx.Stack) after the emulation, and see what offset your desired value is at. bdshemu does not track general values on the stack, so you can't do this directly.

icyfox168168 commented 3 years ago

Thank you, it’s perfect enough. I simulated that the shellcode I wrote is correct. There are tens of thousands of lines of code. I have a little suggestion. If you can make a linked list in the structure, it will be perfect to find the structure of the previous command. I sometimes need to record it. Function jump and stack to determine the end of the function

icyfox168168 commented 3 years ago

I try to simulate strlen, simulate functions, and crash when reading characters. If the parameter is a numerical value, the simulation is perfect, but the parameter is a pointer

icyfox168168 commented 3 years ago

VZEROUPPER

This command simulation is not supported?

vlutas commented 3 years ago

If you can make a linked list in the structure,

The context only records the last instruction emulated. If you wish to see an intermediary context, emulate the instructions one by one. Linking contexts is out of discussion, as it will lead to an extremely high memory overhead when emulating multiple instructions.

I try to simulate strlen, simulate functions, and crash when reading characters. If the parameter is a numerical value, the simulation is perfect, but the parameter is a pointer

I do not understand the inquiry.

This command simulation is not supported?

No. bdshemu is not a general purpose emulator, it is specifically tasked towards shellcodes. Only those instructions which are required to emulate shellcodes are supported.

icyfox168168 commented 3 years ago

I understand that this callback function is needed for external memory

int __add = 0; //#pragma optimize( "", off ) int _llen(char str1, char str2) { if (strlen(str1) > strlen(str2)) { add = 5; } else { add = 6; } return strlen(str1) + strlen(str2) + __add; } //#pragma optimize( "", on )

bool ShemuAccessMem(PSHEMU_CONTEXT Ctx, uint64_t Gla, size_t Size, uint8_t Buffer, bool Store) { UNREFERENCED_PARAMETER(Ctx); UNREFERENCED_PARAMETER(Gla); if (!Store) { memmove(Buffer, (void)Gla, Size); } else { //printf("w %p %p %d %02x \n", Gla, Buffer,Size, *Buffer); MessageBoxA(0, 0, 0, 0); } return true; }