How to replace a store of EAX with a store of an immediate constant? - windows

From my previous question, I asked how to change the nation code to what I needed it to be. I explored in the disassembly more and I found out exactly where I needed this change to be. In other files, the code seems to be:
mov ds:dword_73A9C8, 1
Where the file I'm trying to edit has it like
mov ds:dword_73A9C8, eax
I've tried to edit the file in IDA by hex to match it to the first line of code, however, the function, even after extending its length, seems to break each time I edit it.
The question I have is how can I change it from having eax being moved to having 1 being moved without breaking the function

sub_4A2B60 proc near
arg_0= dword ptr 4
mov eax, [esp+arg_0]
mov ds:dword_73A9C8, eax
retn
sub_4A2B60 endp
You could replace the 4 byte instruction mov eax, [esp + 4] with the sequence xor eax, eax inc eax nop that also has 4 bytes.
If 1 is what you want, then the return value in EAX should probably also be 1.

Related

Why does a function double dereference arguments stored on stack and how is that possible? [duplicate]

This question already has answers here:
Basic use of immediates vs. square brackets in YASM/NASM x86 assembly
(4 answers)
x86 Nasm assembly - push'ing db vars on stack - how is the size known?
(2 answers)
Referencing the contents of a memory location. (x86 addressing modes)
(2 answers)
Why do you have to dereference the label of data to store something in there: Assembly 8086 FASM
(1 answer)
Closed 7 months ago.
I tried to understand "lfunction" stack arguments loading to "flist" in following assembly code I found on a book (The book doesn't explain it. Code compiles and run without errors giving intended output displaying "The string is: ABCDEFGHIJ".) but I can't grasp the legality or logic of the code. What I don't understand is listed below.
In lfunction:
Non-volatile (as per Microsoft x64 calling convention) register RBX is not backed up before 'XOR'ing. (But it is not what bugs me most.)
In portion ";arguments on stack"
mov rax, qword [rbp+8+8+32]
mov bl,[rax]
Here [rbp+8+8+32] dereferences corresponding address stored in stack so RAX should
be loaded with value represented by'fourth' which is char 'D'(0x44) as per my understanding (Why qword?). And if so, what dereferencing char 'D' in second line can possibly mean (There should be a memory address to dereference but 'D' is a char.)?
Original code is listed below:
%include "io64.inc"
; stack.asm
extern printf
section .data
first db "A"
second db "B"
third db "C"
fourth db "D"
fifth db "E"
sixth db "F"
seventh db "G"
eighth db "H"
ninth db "I"
tenth db "J"
fmt db "The string is: %s",10,0
section .bss
flist resb 14 ;length of string plus end 0
section .text
global main
main:
push rbp
mov rbp,rsp
sub rsp, 8
mov rcx, flist
mov rdx, first
mov r8, second
mov r9, third
push tenth ; now start pushing in
push ninth ; reverse order
push eighth
push seventh
push sixth
push fifth
push fourth
sub rsp,32 ; shadow
call lfunc
add rsp,32+8
; print the result
mov rcx, fmt
mov rdx, flist
sub rsp,32+8
call printf
add rsp,32+8
leave
ret
;––––––––––––––––––––––––-
lfunc:
push rbp
mov rbp,rsp
xor rax,rax ;clear rax (especially higher bits)
;arguments in registers
mov al,byte[rdx] ; move content argument to al
mov [rcx], al ; store al to memory(resrved at section .bss)
mov al, byte[r8]
mov [rcx+1], al
mov al, byte[r9]
mov [rcx+2], al
;arguments on stack
xor rbx,rbx
mov rax, qword [rbp+8+8+32] ; rsp + rbp + return address + shadow
mov bl,[rax]
mov [rcx+3], bl
mov rax, qword [rbp+48+8]
mov bl,[rax]
mov [rcx+4], bl
mov rax, qword [rbp+48+16]
mov bl,[rax]
mov [rcx+5], bl
mov rax, qword [rbp+48+24]
mov bl,[rax]
mov [rcx+6], bl
mov rax, qword [rbp+48+32]
mov bl,[rax]
mov [rcx+7], bl
mov rax, qword [rbp+48+40]
mov bl,[rax]
mov [rcx+8], bl
mov rax, qword [rbp+48+48]
mov bl,[rax]
mov [rcx+9], bl
mov bl,0 ; terminating zero
mov [rcx+10], bl
leave
ret
Additional info:
I cannot look at register values just after line 50 which
corresponds to "XOR RAX, RAX" in lfunc because debugger auto skips
single stepping to line 37 of main function which corresponds to
"add RSP, 32+8". Even If I marked breakpoints in between
aforementioned lines in lfunc code the debugger simply hangs so I
have to manually abort debugging.
In portion ";arguments on stack"
mov rax, qword [rbp+8+8+32]
mov bl,[rax]
I am mentioning this again to be more precise of what am asking because question was marked as duplicate and
provided links with answers that doesn't address my specific issue. At line
[rbp+8+8+32] == 0x44 because clearly, mov with square brackets dereferences reference address (which I assume 64bit width) rbp+3h. So, the size of 0x44 is byte. That is why ask "Why qword?" because it implies "lea [rbp+8+8+32]" which is a qword reference, not mov. So if [rbp+8+8+32] equals 0x44, then [rax] == [0x0000000000000044], which a garbage ( not relevant to our code here) address.

x86 Assembly; overwriting .bss values?

I'm currently trying to write a small program in ASM, and I have the following issue. I take input from the user as a string which I store in a variable I've declared in the .bss section of my code; I then re-prompt and overwrite the previously stored answer and do this multiple times. My issue is if someone has entered an answer that was shorter than the last (i.e. "James" then "Jim") I get the following output:
"Hi, James"
"What's your name?"
"Jim"
"Hi, Jimes"
What's happening here is the characters that weren't overwritten remain and get printed, as expected. What I'm wondering is how I may go about wiping the data in the .bss db between prompts?
Here is the code so far:
section .data
question: db "What's your name?", 10
answer: db "Hello, "
ln db 10
section .bss
name resb 16
section .text
global start
start:
call prompt
call getName
mov rsi, answer
mov rdx, 7
call print
mov rsi, name
mov rdx, 10
call print
mov rsi, ln
mov rdx, 1
call print
call loop_name
mov rax, 0x02000001
mov rdi, 0
syscall
reset_name:
loop_name:
mov cx, 3
startloop:
cmp cx, 0
jz endofloop
push cx
loopy:
call getName
mov rsi, answer
mov rdx, 7
call print
mov rsi, name
mov rdx, 10
call print
pop cx
dec cx
jmp startloop
endofloop:
; Loop ended
; Do what ever you have to do here
ret
prompt:
mov rax, 0x02000004
mov rdi, 1
mov rsi, question
mov rdx, 18
syscall
print:
mov rax, 0x02000004
mov rdi, 1
syscall
ret
getName:
mov rax, 0x02000003 ; read
mov rdi, 0
mov rsi, name
mov rdx, 37
syscall
ret
Any ideas? (Variable in question is name)
While I don't know the system calls you're using, we can do one of three things:
clear the entire variable before reusing it.
use and share an explicit length value to indicate how many bytes of it are valid
null terminate the string right after it is input
Using an explicit length value may involve someone placing a null terminator at the right point in time (e.g. just before printing).
The read operation should return to you a length that you can pass to someone else (e.g. as a pair pointer & length), or otherwise use immediately to null terminate the string.  If it doesn't, then use the first approach of clearing the entire variable before reusing it.
Typically, syscalls have return values, that indicate length on success or else negative values for failure.  In such case, you are ignoring both.

Access violation when trying to modify a byte in assembly procedure under NASM Windows

I'm totally new to assembly and I've been coding for about 2 weeks in Linux and able to output certain information on the terminal under Linux. However, today when I began coding under Windows, I ran into a problem, i'm unable to modify a byte in a string that I pass as a parameter to a function. I debugged the program in OllyDbg and it tells me that there's an access violation when writing to [address] - use Shift F7/F8/F9 to pass exception to program. I can't pass the exception to the program since there's no exception handler in the program. Is it illegal to modify a character in a string passed to a procedure? I have posted the code below.
section .bss
var resb 6
section .text
global _start
_start:
xor eax, eax ; empty all registers
xor ebx, ebx
xor ecx, ecx
xor edx, edx
jmp short get_library
get_lib_addr: ; get_lib_addr(char *name)
mov ecx, [esp+8] ; get the first parameter
xor edx, edx ; zero out register
mov byte [ecx+6], dl ; add null terminating character to string
jmp short fin ; go to end
get_library:
xor ecx, ecx
mov ebx, var ; start address of var
jmp start_loop ; start looping
start_loop:
cmp ecx, 5
jge end_loop
mov byte [ebx+ecx], 'h'
inc ecx
jmp start_loop
end_loop:
push dword var ; at this point - var = "hhhhh"
call get_lib_addr ; call get_lib_addr("hhhhh")
fin:
xor eax, eax
mov ebx, 0x750b4b80 ; ExitProcess
push eax ; eax = 0
call ebx ; ExitProcess(0)
And a screenshot of the debugging in OllyDbg.
https://imgur.com/a/48RAXOw
2nd case
Part of the code from Vivid Machines Shellcoding for Linux & Windows is copied below. When I try to use this syntax for passing parameters (assuming that's what is happening), I get an access violation trying to edit the string and adding a null terminating character in place of the N. I'm positive that the string is passed and ecx gets the correct string. Any reason this doesn't work?
LibraryReturn:
pop ecx ;get the library string
mov [ecx + 10], dl ;insert NULL - ***Access violation here***
;the N at the end of each string signifies the location of the NULL
;character that needs to be inserted
GetLibrary:
call LibraryReturn
db 'user32.dllN'
Screenshot of the debug information in the second scenario showing that N is indeed the value being edited.
https://imgur.com/a/W5vdR7d

Why these code is error: instruction operands must be the same size [duplicate]

This question already has an answer here:
Subtract a variable from a register? error A2022: instruction operands must be the same size
(1 answer)
Closed last year.
As I said:
These code:
mov EBX, 0
mov EBX, ofn.nFileOffset
add EAX, EBX ;; error
get error: instruction operands must be the same size.
But when I edit:
mov EBX, 0
mov BX, ofn.nFileOffset
add EAX, EBX
It's ok.
I also test by Ollydbg to track the register but I don't see any different.
Anyone can explain
ofn.nFileOffset is 2 bytes.
and Mov instruction require equal size of 2 argument.
You should try:
xor EBX, EBX
mov BX, ofn.nFileOffset
add EAX, EBX
Now you will have ofn.nFileOffset value in EBX

NASM string from user input not comparing

It's my second day I'm learning NASM and assembly language at all, so I've decided to write a kind of a calculator. The problem is that when user enters the operation, the program doesn't compare it.I mean compares but it doesn't consider that strings are equal when they are. I've googled a lot, but no results. What might be my broblem? Here's source
operV resb 255 ; this is declaration of variable later used to store the input, in .bss of course
mov rax, 0x2000003 ;here user enters the operation, input is "+", or "-"
mov rdi, 0
mov rsi, operV
mov rdx, 255
syscall
mov rax, operV ; here is part where stuff is compared
mov rdi, "+"
cmp rax, rdi
je add
mov rdi, "-"
cmp rax, rdi
je substr
;etc...
You also press the enter key when you submit information like that. change rdi to "+", 10 on linux, or "+", 11 on windows
The answer came to me in a dream last night.
operV resd 4; Resd because registers are a dword in size, and we want the comparison to be as seamless ass possible, you can leave this as 255, but thats a little excessive as we only need 4
mov rax, 0x2000003
mov rdi, 0
mov rsi. operV
mov rdx, 4 ;You only need 4 bytes (1 dword) as this is all we are accepting (+ and line end, then empty space so it matches up with the register we are comparing too) you can leave this as 255 too, but again, we only need 4
syscall
mov rax, operV
mov rdi, "x", 10
cmp dword[rax], rdi ; You were comparing the pointer in rax with rdi, not the content pointed to by rax with rdi. now we are comparing the double word (4 bytes) at the location pointed too by rax (operV) and comparing them. Instead of comparing the location of operV with the thing you want.
je add
That's the changes done :P

Resources