Get char pointer in assembler function - c

I need to get my char pointer and after that i print it on the screen to see if it works ok.
I read the text from a file and put in my char pointer (sizeof(char*) + filesize) + 1.. in the end i put the '\0'.
If i printf my char* its fine
Here is my asm code
; void processdata(char* filecontent);
section .text
global processdata
extern printf
section .data
FORMAT: db '%c', 10, 0 ; to break the line 10, 0
processdata:
push ebp
mov ebp, esp
mov ebx, [ebp]
push ebx
push FORMAT
call printf
add esp, 8
when i run it i just see trash in my variable.
As violet said:
; void processdata(char* filecontent);
section .text
[GLOBAL processdata] ;global processdata
extern printf
section .data
FORMAT: db '%c', 0
EQUAL: db "is equal", 10, 0
processdata:
lea esi, [esp]
mov ebx, FORMAT
oook:
mov eax, [esi]
push eax
push ebx
call printf
inc esi
cmp esi, 0x0
jnz oook
Thanks

quote demonofnight
But if i need to increment, can i do that?
Using your original function arg of char* and your %c format, something like this:
lea esi, [esp+4]
mov ebx, FORMAT
oook:
mov eax, [esi]
push eax
push ebx
call printf
inc esi
cmp [esi], 0x0
jnz oook
[edit: ok sry, i hacked that quickly into some shenzi winOS inline __asm block]
here's a complete thing done in linux and nasm:
; ----------------------------------------------------------------------------
; blah.asm
; ----------------------------------------------------------------------------
extern printf
SECTION .data ;local variables
fmt: db "next char:%c", 10, 0 ;printf format, "\n",'0'
SECTION .text ;hack in some codes XD
global foo
foo: ;foo entry
push ebp ;set up stack frame
mov ebp,esp
mov esi, [ebp+8] ;load the input char array to the source index
oook: ;loop while we have some chars
push dword [esi] ;push next char addy in string to stack
push dword fmt ;push stored format string to stack
call printf
add esp, 8 ;restore stack pointer
inc esi ;iterate to next char
cmp byte [esi], 0 ;test for null terminator byte
jnz oook
mov esp, ebp ;restore stack frame
pop ebp
mov eax,0 ;return 0
ret ;done
blah.c (that invokes the .asm foo) :
/*-----------------------------------------------
blah.c
invokes some asm foo
------------------------------------------------*/
#include <stdio.h>
void foo(char*);
int main() {
char sz[]={"oook\n"};
foo(sz);
return 0;
}
&here's the commandline stuff:
$ nasm -f elf blah.asm -o blah.o
$ gcc -o blah blah.c blah.o
$ ./blah
next char:o
next char:o
next char:o
next char:k
next char:
$
$ nasm -v
NASM version 2.09.08 compiled on Apr 30 2011
$ uname -a
Linux violet-313 3.0.0-17-generic #30-Ubuntu SMP Thu Mar 8 17:34:21 UTC 2012 i686 i686 i386 GNU/Linux
Hope it works for you ;)

On linux x86 the first function parameter is in ecx. The printf format for printing a pointer is "%p".
So something along
...
FORMAT: db '%p', 10, 0 ; to break the line 10, 0
processdata:
mov eax, [esp+4]
push eax
push format
call printf
add esp, 8
ret
should work, assuming the rest of your code is correct and your are using gcc's calling convention.
This is assuming that the pointer you want to print is on the stack.
The reason for the crash is probably that you push 12 bytes on the stack, but correct the stack pointer by only 8.

Related

returning Assembly Function In C Code x86 Compilation on 64 bit linux

C code
#include <stdio.h>
int fibonacci(int);
int main()
{
int x = fibonacci(3);
printf("Fibonacci is : %d",x);
return 0;
}
Assembly
section .text
global fibonacci
fibonacci:
push ebp;
mov ebp, esp;
; initialize
mov dword [prev], 0x00000000;
mov dword [cur], 0x00000001;
mov byte [it], 0x01;
mov eax, dword [ebp + 8]; // n = 3
mov byte [n], al;
getfib:
xor edx,edx;
mov dl, byte [n];
cmp byte [it] , dl;
jg loopend;
mov eax,dword [prev];
add eax, dword [cur];
mov ebx, dword [cur];
mov dword [prev], ebx;
mov dword [cur] , eax;
inc byte [it];
jmp getfib;
loopend:
mov eax, dword [cur];
pop ebp;
ret;
section .bss
it resb 1
prev resd 1
cur resd 1
n resb 1
I was trying to run this assembly function in C code and on debugging , i saw that value in variable x in C code is right but there is some error coming when i use the printf function
Need Help on it
Command to compile:
nasm -f elf32 asmcode.asm -o a.o
gcc -ggdb -no-pie -m32 a.o ccode.c -o a.out
Click Below Pictures if they seem blurred
Below is debug before printf execute
Below is after printf execute
Your code does not preserve the ebx register which is a callee-preserved register. The main function apparently tries to do some rip-relative addressing to obtain the address of the format string for printf using ebx as a base register. This fails because your code overwrote ebx.
To fix this issue, make sure to save all callee-saved registers before you use them and then restore their value on return. For example, you can do
fibonacci:
push ebp
mov ebp, esp
push ebx ; <---
...
pop ebx ; <---
pop ebp
ret

how to pass a variable by reference to a c function `sscanf()`

the following code tries to read the command line arguments and then scans them with sscanf() and use the result to emit utf8 text.
I'm failing to call sscanf() and getting segfault error at the line where I call this function
I have already debugged this and I know where is the problem but not how to solve it.
global main
extern puts
extern sscanf
extern printf
extern emit_utf_8
section .text
main:
cmp rdi, 2
jl argumentsError
add rsi, 8 ; skip the name of the program
forloop:
mov r12, rsi
push rdi
push rsi
push r12
sub rsp, 8 ; must align stack before call
; start of for bloc
xor rax, rax
mov rdi, qword [r12]
mov rsi, codePointFormat
mov rdx, qword [codePoint]
call sscanf
cmp rax, 1
je ifthen
jmp else
ifthen:
mov rdi, codePoint
call emit_utf_8
jmp endif
else:
mov rdi, incorrectFormat
mov rsi, r12
call printf
endif:
; end of for bloc
add rsp, 8 ; restore %rsp to pre-aligned value
pop r12
pop rsi
pop rdi
add rsi, 8 ; point to next argument
dec rdi ; count down
jnz forloop ; if not done counting keep going
ret
argumentsError: mov rdi, argumentsRequiredMessage
call puts
mov rdi, argumentDescription
call puts
xor rax, rax
inc rax
ret
section .data
argumentsRequiredMessage:
db "This program requires one or more command line arguments,", 0
argumentDescription: db "one for each code point to encode as UTF-8.", 0
incorrectFormat: db "(%s incorrect format)", 0
codePointFormat: db "U+%6X", 0
section .bss
codePoint: resb 8 ; The code point from sscanf should go here.
Is there a way to pass that third argument?
sscanf() signature.
in __cdecl sscanf(const char *const _buffer, const char *const _Format, ...)
I'm using ubuntu 19.04 64 bit

EggHunter not finding the egg, causing infinite loop

EggHunter not finding the egg (32bit), causing infinite loop
I have 1 example, that prints We found the egg! which works, and another the prints Hello egg! that isn't working.
Both use the same egg 0x90f890f9
I think the problem may be here:
cmp dword [ecx], 0x90f890f9 ; marker
Here is the c code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
unsigned char egghunter[21];
void main()
{
/* works OK (We found the egg!)
"\x90\xf9\x90\xf8\x90\x68\x21\x0a\x0a\x0a\x68\x20\x65\x67\x67\x68\x20\x74\x68"
"\x65\x68\x6f\x75\x6e\x64\x68\x57\x65\x20\x66\x31\xc9\xb1\x12\x51\xb8"
"\x11\x11\x51\x08\x50\x31\xc0\x50\x54\x51\x89\xe6\x83\xc6\x14\x03\x74"
"\x24\x10\x2b\x34\x24\x56\x89\xf1\xeb\x1c\xeb\x0c\x59\x59\xe2\xe8\x31"
"\xdb\x31\xc0\xb0\x01\xcd\x80\x31\xc0\xb0\xa2\x8d\x5c\x24\x0c\x31\xc9"
"\xcd\x80\xeb\xe6\x31\xd2\xb2\x01\x31\xdb\xb3\x01\x31\xc0\xb0\x04\xcd"
"\x80\xeb\xd4";
*/
/* gives an infinite loop (suppose to print Hello egg!)
"\x90\xf9\x90\xf8\x90\xeb\x17\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x59\x31\xd2\xb2\x0b\xcd\x80"
"\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff\x48\x65\x6c\x6c"
"\x6f\x20\x65\x67\x67\x21\x0a";
*/
unsigned char shellcode[256] = \
"\x90\xf9\x90\xf8\x90\xeb\x17\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x59\x31\xd2\xb2\x0b\xcd\x80"
"\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff\x48\x65\x6c\x6c"
"\x6f\x20\x65\x67\x67\x21\x0a";
printf("Shellcode: %d bytes\n", strlen(shellcode));
strcpy(egghunter,"\xeb\x0e\x59\x83\xe9\x17\x81\x39\xf9\x90\xf8\x90\xe0\xf8\xff\xe1\xe8\xed\xff\xff\xff");
printf("Egghunter: %d bytes\n", strlen(egghunter));
int (*ret)() = (int(*)())egghunter;
ret();
}
Here is the egghunter code:
global _start
section .text
_start:
jmp call_egghunter
egghunter:
pop ecx ; save addr ptr
sub ecx, 23 ; move addr ptr back
next:
cmp dword [ecx], 0x90f890f9 ; marker
loopnz next ; dec ecx, jump
jmp ecx ; jump to shellcode
call_egghunter:
call egghunter
And the hello egg code that isn't working is:
global _start
section .text
_start:
jmp short call_shellcode
shellcode:
; print hello world on the screen
xor eax, eax
mov al, 0x4
xor ebx, ebx
mov bl, 0x1
pop ecx
xor edx, edx
mov dl, 11
int 0x80
; exit the program gracefully
xor eax, eax
mov al, 0x1
xor ebx, ebx
int 0x80
call_shellcode:
call shellcode
message: db "Hello egg!", 0xA
Your egghunter is a global variable which lives in the data section. Your shellcode is a local variable which lives on the stack. You search for the mark from egghunter downwards, however the usual layout on linux (which I assume you use due to the int 0x80) places the stack above the data section. As such, you are searching in the wrong direction, and whatever you are finding is not your shellcode. In fact, it is part of the code that does the strcpy(egghunter, literal):
0x80494fe: movl $0x90f890f9,0x80497d0
0x8049508: movl $0xe1fff8e0,0x80497d4
0x8049512: movl $0xffffede8,0x80497d8
0x804951c: movw $0xff,0x80497dc
0x8049525: movl $0x80497c8,(%esp)
Learn to use a debugger so you can step through the code and see what it is doing.

NASM 32-bit: printing content of register by printf

I'm new to assembly. I'm having different output for following simple code from what I expected. each time before printf is called, content of eax is shifted to the right by some number. What am I doing wrong? Thanks.
Code:
;file name : testing.asm
;assemble and link with:
;nasm -f elf testing.asm && gcc -m32 -o testing testing.o
extern printf ; the C function, to be called
SECTION .data ; Data section, initialized variables
a: dd 15 ; int a=15
str: db "content in eax=%d", 10, 0
SECTION .text ; Code section.
global main ; the standard gcc entry point
main: ; the program label for the entry point
mov ebp, esp
mov eax, [a] ; put a from store into register
shr eax, 1 ; eax content should be 15>>1 = 7
push eax
push dword str ; string to be printed
call printf ; printf(str,content_of_eax)
shr eax, 2
push eax ; eax content should be 7>>2 = 1
push dword str
call printf ; printf(str,content_of_eax)
shr eax, 1
push eax ; eax content should be 1>>1 = 0
push dword str
call printf ; printf(str,content_of_eax)
mov esp, ebp ; takedown stack frame
mov eax, 0 ; normal, no error, return value
ret ; return
Output:
content in eax=7
content in eax=4
content in eax=8
Expected Output:
content in eax=7
content in eax=1
content in eax=0
printf returns its result in eax, the original value is lost.
You should reload it from [a] or use a register that is saved across function calls such as esi, but you should save it as well and restore it before returning to the caller. You should pop the arguments passed to printf with a add esp,8 after each call to keep your stack frame consistent.
In your data section you could just use an equate for a since you only use that variable once and do not change it (i'll call it value).
fmt db "content in eax=%d",0xa,0
value equ 15
In the main function i'm pretty sure (correct me if i'm wrong) that you're supposed to save the base pointer before you update it with the stack pointer.
main:
push ebp
mov ebp, esp
Now you could create a local variable to store the current value you are working on.
sub esp, 4
From there you would just keep fetching, shifting and storing the value on the stack before each call to printf.
mov eax, value ; move 15 into eax
shr eax, 1 ; make first shift
mov dword[ebp-4], eax ; store result in local variable
push eax ; eax = 7
push fmt
call printf
add esp, 8 ; clean eax & fmt off the stack
mov eax, [ebp-4] ; fetch last shift result from variable
shr eax, 2 ; make second shift
mov dword[ebp-4], eax ; store result back in variable
push eax ; eax = 1
push fmt
call printf
add esp, 8
mov eax, [ebp-4] ; fetch last shift result from variable
shr eax, 1 ; make last shift
push eax ; eax = 0
push fmt
call printf
add esp, 8
add esp, 4 ; clean local variable
And then remember, before you return, when you release the stack frame that you also restore (pop) the base pointer.
mov esp, ebp
pop ebp
This should output:
content in eax=7
content in eax=1
content in eax=0
Remember that printf will return the number of characters transmitted to the output. So when you do this:
call printf ; printf(str,content_of_eax)
shr eax, 2
You are actually shifting the result from printf:
"content in eax=7\n" is 17 characters, so shitfting by 2 gives: 17 / 4 = 4
You need to save the value (either in a preserved register, on the stack or in memory) before shifting.
This answer seems not to be a good solution, I'm currently keeping it because of the discussion below
Like others said, printf will return it's result to eax. The result of printf is the number of bytes written.
Since you pushed the result of the shr operation to the stack, you can retrieve them again using pop, like this:
shr eax, 1 ; eax content should be 15>>1 = 7
push eax
push dword str ; string to be printed
call printf ; printf(str,content_of_eax)
pop eax
pop eax
shr eax, 2
push eax ; eax content should be 7>>2 = 1
push dword str
call printf ; printf(str,content_of_eax)
# and so on ...

Printing out Twice NASM

My question: Why is it printing twice when I'm making one call to printf?
Note that yes, I'm aware I'm allocating space in heap for a variable stored on the stack. I'm only doing this to get used to malloc, pointers, and 'arrays' in NASM.
Compiling in x64 bit machine with:
nasm -f elf32 -o TEMP.o file.asm
and:
gcc -m32 -o exec TEMP.o
extern exit, printf, malloc, free
global main
section .data
format db "%s", 10
msg: db "Hello!!",10
BUF equ $-msg + 1
section .text
main:
push BUF ; How many bytes do we want to allocate
call malloc ; ptr stored in EAX
add esp, 4 ; clear the last thing on the stack (BUF)
mov esi, eax ; new source index at malloc pointer
xor ecx, ecx ; clear ECX (counter for us)
loop:
mov dl, [msg+ecx] ; mov letter into dl
mov BYTE [esi+ecx], dl ; cat dl onto array
inc ecx ; add 1 to our ounter
cmp ecx, BUF-1d
jl loop
xor edx, edx
mov BYTE [esi+ecx], dl
add esp, 4
mov esi, eax
push esi ;
push format
call printf
add esp, 4*2
push esi
call free
push 0
call exit
add esp, 4
You only need to end your strings with 0
format db "%s", 10, 0
msg: db "Hello!!",10 ,0
Okay i'v read the comments just now and see you said you had code that is meant to insert the 0s, i'd check that, because i copied/pasted your code and only added the 0s on the ends of the strings to make it output one string, i didn't even notice the insertion code let alone touch it, but i can only assume that is where your problem is.

Resources