Assembly - visualise registers, stack etc - debugging

Hej, I was writing my programs on emu8086, and I used it for debugging. However now I need to use floating points, FPU and emu8086 doesn't support them. I need an easy way to see what is in certain place of memory. For example visualise: "dzielna", "dzielnik", the content of register such as ax, bx,.. ; and what is in st(0), st(1) etc. Shall you recommend me a good program to visualise it?
dane1 segment
dzielna dd 1.3
dzielnik dd 6.7
dane1 ends
assume cs:code1, ss:stos1, ds:dane1
stos1 segment stack
dw 400 dup(?)
top1 dw ?
stos1 ends
code1 segment
.386
.387
start1: mov ax,seg top1
mov ss,ax
mov sp,offset top1
mov ax,dane1
mov ds,ax
finit
fldpi
fld dword ptr [dzielna]
fld dword ptr [dzielnik]
fsub st(0),st(1)
fstp dword ptr [dzielna]
finish:
mov ah,4ch
int 21h
code1 ends
end start1

The program to visualise it is called a debugger. Since you are running in DosBox you need one that can be run there.
If you can get your hands on Turbo Assembler - it has a debugger TD.exe
OpenWatcom also has a debugger that can be run in DosBox
and both allows you to show the FPU registers.

Related

Why is my branch instruction not jumping to the given address?

I'm currently learning reverse engineering and therefore I need to learn assembly. The code is running well, but I got an error on JE and JNE instructions. To be more specific: I'm doing a detour hook as a practice and the program crashes, because it jumps to the false address.
I wanted to write this, but the compiler gave me an error (LNK2016):
JE 0x123 (0x123 example address)
I fixed that problem by writing:
JE short 0x123
Full function code:
my_hook:
push rbp
mov rbp, rsp
mov dword [rcx + 0x18], 99
test rcx, rcx
je 0x7FF7847902EE
lock dec dword [rcx + 0x08]
jne 0x7FF7847902EE
mov rcx, [rsp + 0x30]
leave
ret
But the problem now is, that it is jumping to the beginning of the function instead of 0x123 in our case.
The conditional jump instructions on x86 all take a relative displacement, not an absolute address. They work to jump to another label in your code, since the assembler can compute the displacement between the jump instruction and the destination, but you can't use them jump to an absolute address unless you know, at assembly time, the address where your code will be loaded.
Near absolute jumps on x86 are indirect: you need to have the address in a register or memory. And such jumps are only available in an unconditional form, so you'll have to use the conditional jump to get to them.
You could do
my_hook:
push rbp
mov rbp, rsp
mov dword [rcx + 0x18], 99
test rcx, rcx
je jump_elsewhere
lock dec dword [rcx + 0x08]
jne jump_elsewhere
mov rcx, [rsp + 0x30]
leave
ret
jump_elsewhere:
mov rax, 0x7FF7847902EE
jmp rax
If you can't spare a register, you could instead do
jump_elsewhere:
jmp [rel elsewhere_addr]
elsewhere_addr:
dq 0x7FF7847902EE
but this is more bytes of code.
If you do know the address where your code will be loaded, and it's within 2 GB of the destination address, you can use the ORG directive to tell the assembler about it. So if my_hook will be at address 0x7ff7DEADBEEF, you can do
org 0x7ff7DEADBEEF
my_hook:
; ...
je 0x7FF7847902EE
and the assembler will compute the correct 32-bit displacement.
By the way, the test rcx, rcx doesn't really make sense: if rcx were zero then the previous instruction mov dword [rcx + 0x18], 99 would have faulted, since on any decent operating system, the zero page will be unmapped. Maybe you wanted this test and conditional jump to go before the mov. Unless this is some sort of strange bare-metal code that you're patching?

What is the GENERIC_WRITE constant hex value in windows?

I'm trying to open a file for writing using the CreatFileA system call in assembly in x64, however in order to do so I need to specify the desired access. I don't know what the constant is for GENERIC_WRITE, the GENERIC_READ constant is 80000000h.
; create the file
lea rcx, fileName
mov rdx, 40000000h
xor r8, r8
xor r9, r9
mov QWORD PTR [rsp+48h-28h], 2
mov QWORD PTR [rsp+48h-20h], 80h
mov QWORD PTR [rsp+48h-18h], 0
call CreateFileA
mov FD2, rax
; write to the new file
lea rcx, FD2
lea rdx, buffer
mov r8, len
lea r9, written
mov QWORD PTR [rsp+48h-28h], 0
call WriteFile
mov writeResult, rax
Turning the comments into an answer so this can get closed out.
As Michael points out, the bits that make up the Access Mask are defined here.
Using that we see that GENERIC_READ is 0x80000000 and GENERIC_WRITE is 0x40000000.
Generally speaking, you should probably look at Windows' headers to get the definitive and most up-to-date values for all Windows constants. This one is in Winnt.h.
Addressing the follow-on question, your assembler code to load the handle to be passed to WriteFile is incorrect. You are saving the value returned from CreateFile using
mov FD2, rax
But then you load it back using
lea rcx, FD2
lea is going to return a pointer to the handle, not the handle itself.
So, for once, Windows was really being helpful when it returned the The handle is invalid error message. (By implication) it told which parameter was the source of the problem, and (roughly) what the problem was.

Windows32 API: "mov edi,edi" on function entry?

I'm stepping through Structured Error Handling recovery code in Windows 7
(e.g, what happens after SEH handler is done and passes back "CONTINUE" code).
Here's a function which is called:
7783BD9F mov edi,edi
7783BDA1 push ebp
7783BDA2 mov ebp,esp
7783BDA4 push 1
7783BDA6 push dword ptr [ebp+0Ch]
7783BDA9 push dword ptr [ebp+8]
7783BDAC call 778692DF
7783BDB1 pop ebp
7783BDB2 ret 8
I'm used to the function prolog of "push ebp/mov ebp,esp". What's the purpose
of the "mov edi,edi"?
Raymond Chen (one of the Microsoft developers) has answered this exact question:
Why do Windows functions all begin with a pointless MOV EDI, EDI instruction?
And he links an even earlier reference:
Why does the compiler generate a MOV EDI, EDI instruction at the beginning of functions?
Basically, it leaves space for a jump instruction to be inserted during hot patching.

Linker replacing valid code with invalid code

So I've got a very strange and specific problem here. We're putting seemingly valid code into a linker, and then the linker is making some mistakes, like removing a valid ptr label and instead of replacing it with a value, it's putting in 0 instead. But not everywhere either. It starts at a pretty arbitrary point.
So, some background: we have an interpreted language that is converted into assembly by putting together hand-generated chunks of assembly (by an in-house compiler-like application) and adding in variables where required. This is a system that has been working for around 10 years if not longer, in pretty much it's current form, so the validity of this method is not currently in question. This assembly is assembled to an obj file using the Microsoft Assembler (ml.exe or MASM).
Then in a separate step, this obj file is linked using the Microsoft Incremental Linker together with some other libraries (static, and import libraries for dlls) to create an executable.
Following is a portion of the assembly (.asm) file that the assembler outputs when it creates the obj file in the first step:
call _c_rt_strcmp
mov di, 1
mov ebp, esp
cmp ax, 0
je sym2148
dec di
sym2148: mov [ebp+6], di
add esp, 6
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0bb49h
pop ax
mov byte ptr [ebx],al
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 012656h
push ebx
mov eax, OFFSET sym2151
push eax
call _c_rt_strcmp
mov di, 1
mov ebp, esp
cmp ax, 0
je sym2152
dec di
sym2152: mov [ebp+6], di
add esp, 6
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0bb32h
pop ax
mov byte ptr [ebx],al
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 012656h
push ebx
mov eax, OFFSET sym2155
push eax
call _c_rt_strcmp
mov di, 1
mov ebp, esp
cmp ax, 0
je sym2156
dec di
sym2156: mov [ebp+6], di
add esp, 6
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0bb4ah
pop ax
mov byte ptr [ebx],al
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0126bbh
push ebx
mov eax, OFFSET sym2159
push eax
call _c_rt_strcmp
As far as I can see, that is correct, and makes sense. I believe that code that generates this does a string compare and then stores a value based on the result of the string compare, and it's a section of 20-30 of them, so there are 10 or so more groups before the first bit I posted, and about 15-20 after the last bit I posted.
Following is the disassembled view of the crash location that Visual C++ 5.0 (old I know, but this is on a legacy system unfortunately) shows when the executable crashes:
004093D2 call 00629570
004093D7 mov di,1
004093DB mov ebp,esp
004093DD cmp ax,0
004093E1 je 004093E5
004093E3 dec di
004093E5 mov word ptr [ebp+6],di
004093E9 add esp,6
004093EC mov ebx,dword ptr ds:[64174Ch]
004093F2 add ebx,0BB49h
004093F8 pop ax
004093FA mov byte ptr [ebx],al
004093FC mov ebx,dword ptr ds:[64174Ch]
00409402 add ebx,12656h
00409408 push ebx
00409409 mov eax,0
0040940E push eax
0040940F call 00409414
00409414 mov di,1
00409418 mov ebp,esp
0040941A cmp ax,0
0040941E je 00409422
00409420 dec di
00409422 mov word ptr [ebp+6],di
00409426 add esp,6
00409429 mov ebx,dword ptr ds:[0]
0040942F add ebx,0BB32h
00409435 pop ax
00409437 mov byte ptr [ebx],al
00409439 mov ebx,dword ptr ds:[0]
0040943F add ebx,12656h
00409445 push ebx
00409446 mov eax,0
0040944B push eax
0040944C call 00409451
00409451 mov di,1
00409455 mov ebp,esp
00409457 cmp ax,0
0040945B je 0040945F
0040945D dec di
0040945F mov word ptr [ebp+6],di
00409463 add esp,6
00409466 mov ebx,dword ptr ds:[0]
0040946C add ebx,0BB4Ah
00409472 pop ax
00409474 mov byte ptr [ebx],al
00409476 mov ebx,dword ptr ds:[0]
0040947C add ebx,126BBh
00409482 push ebx
00409483 mov eax,0
00409488 push eax
00409489 call 0040948E
The actual crash location is 0x00409429.
The two bits of code match, as in they are the same section of code, except the first from the .asm file is what is going into the linker, and the second one is that has come out of the linker.
From what I can see, it's crashing at that location because it's attempting to de-reference an address of 0, right? So of course that's going to fail. Also, if you take a look at the different function calls at 0x004093D2, 0x0040940F, 0x0040944C and 0x00409489, only the first one is valid, the others are simply doing a function call to the line directly after them! And this broken code continues on for the next 15-20 similar segments of code that is defined in that file.
If you look at the corresponding lines for the function calls and the bad pointers in both sections, you will see that in the .asm file everything appears to be correct, but somehow the linker just breaks it all when it compiles the exe, and in a very specific spot, as there are similar chunks of code previous in the file which are constructed correctly.
We do get some linker warnings of the form: "LINK : warning LNK4049: locally defined symbol "_smfv1_ptr" imported". But we were getting those same warnings even when it was working.
The assembler used was ml.exe version 6.11, and the linker was link.exe version 5.10.7303 which were both the version from Visual C++ 5.0. Since the assembled code seems to be right, I'm going to be trying the linker from Visual Studio 2005, 2008 and 2010 and see if anything changes.
I can't really imagine what could create this kind of error, and I thought maybe it was symbols getting messed up, but there are jumps to locations (for small 'if' statements) which are stored as symbols which still work fine after they get through the linker.
Is it possible that a symbol table or something similar is getting overloaded inside the linker, and it's just reverting to bad or default values?
Call to the following address is a clear sign of unresolved symbol reference (it makes sense if you notice that all calls in .obj files are emitted as E8 00 00 00 00). You have zeroes for some data references as well (sym2151, some references to _smfv1_ptr, sym2159). What's strange is that the first call to _c_rt_strcmp did get resolved. I would suggest turning on all warning/debugging/verbose switches that you can find, and generating all kinds of listing and map files. Maybe something will jump out.
Okay, so the end result seems to be that it is a bug with the Visual C++ version of the masm assembler "ml.exe" (big surprise, huh?)
So, moving to the versions of masm and link that were provided in Visual Studio 2005 seems to be the best solution for us.
Thanks for your help guys :)

ComputerID in Qt

Well, i just need a way to get Windows ComputerID (Hardware based), an ID that doesn't change, or something similar, unchangeable unless you do hardware changes in your PC.
Qt does not provide such a functionality. All you can do is to calculate such a value from the existing hardware, like the CPU, the installed hard disks and/or the MAC address. None of these approaches provides an fully satisfying solution to your problem.
The use the CPU for a hardware based ID you can use the Assembler command CPUID: http://en.wikipedia.org/wiki/CPUID, http://www.sandpile.org/ia32/cpuid.htm provide some detailed information.
QByteArray CPU_Vendor_Name()
{
char Vendor[13];
_asm
{
// EAX = 0: Get CPU manufacturer
XOR EAX, EAX
CPUID
MOV EAX, EBX
MOV Vendor[0], al
MOV Vendor[1], ah
SHR EAX, 16
MOV Vendor[2], al
MOV Vendor[3], ah
MOV EAX, EDX
MOV Vendor[4], al
MOV Vendor[5], ah
SHR EAX, 16
MOV Vendor[6], al
MOV Vendor[7], ah
MOV EAX, ECX
MOV Vendor[8], al
MOV Vendor[9], ah
SHR EAX, 16
MOV Vendor[10], al
MOV Vendor[11], ah
MOV Vendor[12], 00
}
return QByteArray(Vendor);
}
This will return "GenuineIntel" for all intel processors and "AuthenticAMD" for AMD processor. This is quite useless, but with other parameters in the EAX register you get detailed information about the processor (detailed model, features, etc.). You can use this to calculate an ID (for example: SHA(Vendor, Model, BrandID, CPUCount)) etc. But bear in mind that the same processor will always result in the same ID.
You can enrich your ID with the MAC address (= SHA(Vendor, ..., MAC)), but the MAC address can be changed, although it's not very likely that the average computer will do that frequently.
In case you want to implement some sort of copy protection, remember that every copy protection can be cracked, so you shouldn't punish your users with a very sophisticated protection that limits the use of your software for them.
I realize that this is an old post, but I came across this document and had to post it because it explains the CPUID and the process of extracting the CPU information from the chip. Not that #Wolfgang Plaschg was in any way incorrect. As a newb, his answer made some sense but there was a slight level of abstraction that I wasn't seeing through at first. Maybe this can help other newbs too... This is the document from Intel:
http://download.intel.com/design/PentiumIII/applnots/24512501.pdf
if the link fails or is no longer available, search for the Intel AP-909 Application Note. Also, this link is of some help too:
https://software.intel.com/en-us/forums/topic/308483
Enjoy!

Resources