On Tue, 2 Nov 2010 23:06:05 +0200
Amr Thabet <amr.tha...@student.alx.edu.eg> wrote:

> Hello Mr. Edwin,
> 
> >The real ones, or will wine's version do?
> >Do you need the actual code in them, or just the export tables?
> 
> it's really a linux version and it only needs the export table not
> the real code. we could create a modified kernel32.dll and ntdll and
> so on with inly the export table to decrease its size

OK, so in that sense it is like libemu (they have the exports table
included in their code).

> 
> >I don't know yet. Looks like I'm hitting some portability issues now:
> >- missing <cstdio> and <cstring> include (otherwise fails to build
> >with gcc 4.4)
> >- dbg/dbg.cpp has x86 assembly code, so it won't work on x86-64:
> >:71: Error: operand type mismatch for `push'
> >Is there a way to disable that part of the code?
> 
> it simply do the following
> 
> mov eax,XXX
> mov ebx,XXX
> call ecx
> 
> it could be converted into x64 but that's not the problem
> 
> the problem is the parser in the dbg as it creates a 32-bit Assembly
> Code that test the breakpoint like:
> 
> addbp("ecx==0x5678");
> 
> the parser converts this into
> 
> mov eax,0x5678
> mov ecx,eax
> mov eax,dword ptr [&Thread.ecx - &Thread]
> test eax,ecx
> jz Lable1
> mov eax,0
> ret
> Label1:
> mov eax,0
> ret
> 
> this call is executed every time it emulates an instruction

Why do you need to generate assembly code to compare Thread.ecx with
something? Is it that much faster?
You could simply put a function pointer in your structure, a pointer to
the value you want to compare, and the constant to compare to.
Then compare using C code, not assembly.

.func = compare_values
.lhs = (char*)&Thread.ecx - (char*)&Thread
.rhs = 0x5678

Then call ->func(bp->lhs, bp->rhs), and compare_values would
do *(uint32_t*)((char*)Thread + bp->lhs) == bp->rhs.

> I think this code couldn't be executed on x64 so it's hard to convert
> the emulator to work on x64

I compiled with -m32, so it is executed as 32-bit code.
Hint: you can run your program under valgrind on Linux.
It is an excellent memory debugger.

It shows errors like this in your code, looks like you are consistently
off by 4 bytes.

==30022== Invalid read of size 4
==30022==    at 0x48E2299: op_pushad(Thread&, ins_disasm*) (jmps.cpp:80)
==30022==    by 0x48E8412: Process::emulate() (process.cpp:193)
==30022==    by 0x80491E7: main (in /home/edwin/X86
Emulator/examples/02/a.out)
==30022==  Address 0x70a072c is 0 bytes
after a block of size 68 alloc'd 
==30022==    at 0x48AF72E: operator
new(unsigned int) (vg_replace_malloc.c:255) 
==30022==    by 0x48E7E91:
Process::CreateThread(unsigned long) (process.cpp:114) 
==30022==    by
0x48E7E07: Process::Process(System*, std::string) (process.cpp:100)
==30022==    by 0x8048F82: main (in /home/edwin/X86
Emulator/examples/02/a.out)

==30022== Invalid write of size 4
==30022==    at 0x48EE787: op_stos(Thread&, ins_disasm*)
(strings.cpp:65) ==30022==    by 0x48E8412: Process::emulate()
(process.cpp:193) ==30022==    by 0x80491E7: main (in /home/edwin/X86
Emulator/examples/02/a.out) ==30022==  Address 0x70a072c is 0 bytes
after a block of size 68 alloc'd ==30022==    at 0x48AF72E: operator
new(unsigned int) (vg_replace_malloc.c:255) ==30022==    by 0x48E7E91:
Process::CreateThread(unsigned long) (process.cpp:114) ==30022==    by
0x48E7E07: Process::Process(System*, std::string) (process.cpp:100)
==30022==    by 0x8048F82: main (in /home/edwin/X86
Emulator/examples/02/a.out)

... ==30119== ERROR SUMMARY: 1695990 errors from 324 contexts
(suppressed: 15 from 6)

The code doesn't crash when run under valgrind (because it prints the
error, and continues). Once you fix the valgrind warnings I'm sure
it'll work better without it too.

Another hint: valid indexes for Thread::dword Exx[7] are from 0 to 6,
you have for loops that go from 0 to 7 (inclusive).
You should review your code and make sure you declare and use
appropriate bounds.

> 
> 
> >- with -m32 the first example works, but the 2nd example tries to
> >execute some code in TestBP. What code is it trying to execute?
> >It wouldn't be wise to execute the malware code on the real CPU ...
> >thats the point of having an emulator in the first place
> >
> >Program received signal SIGSEGV, Segmentation fault.
> >0x08078e98 in ?? ()
> >(gdb) bt
> >#0 0x08078e98 in ?? ()
> >#1 0xf7fedd39 in Debugger::TestBp (this=0x806b8c8, num=0, thread=...,
> >ins=0x8078de8) at dbg/dbg.cpp:39
> >#2 0xf7fedda9 in Debugger::TestBp (this=0x806b8c8, thread=...,
> >ins=0x8078de8) at dbg/dbg.cpp:48
> >#3 0xf7fe82f9 in Process::emulate (this=0x805fe68) at process.cpp:179
> >#4 0x08049239 in main (argc=1, argv=0xffffd354) at main.cpp:58
> >
> 
> sometimes it returns error. but it's not execute the malware in the
> real CPU but the breakpoint testing procedure only

OK, that makes sense.

> 
> >is your code supposed to work on Linux, or would I be better of
> >testing in on Windows first?
> 
> it works on Windows mainly but it should run on linux with no
> problems . but sometimes it returns Segmentation Fault
> 
> if there's something like SEH on Linux or any exception handler that
> will be great

You can intercept SIGSEGV, but that is not the way to go in a portable
program.
You have to avoid the segmentation fault in the first place,
for example by checking that your memory access is in bounds, *before*
the access.

> 
> >I think I'll write an app that uses libclamav, multiple emulators,
> >and compares their execution.
> >I think contrib/ would be good place for such an app.
> >Then I'll scan part of our zoo with it, and see how much it can
> >emulate.
> 
> surely no emulator hasn't any bug . nearby most of them contain bugs
> and error in emulation. but the emulators like bochs and vmware they
> tested hundreds of times so there's no real bugs
> 
> 
> For any emulator you choose you do many beta testing and many fixing
> as it will be a part of your project (clamav)

I agree about the testing part, but bugfixing should be done by the
emulator's author.

> 
> about compiling I test it again and it compiled perfectly perfectly
> on gcc 4.0.1 with string.h as I think

gcc 4.4 is more strict about C++ headers. They cleaned up a lot of
useless includes, so code that was not entirely ISO standards compliant
may get compile errors.

Best regards,
--Edwin
_______________________________________________
http://lurker.clamav.net/list/clamav-devel.html
Please submit your patches to our Bugzilla: http://bugs.clamav.net

Reply via email to