Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用外壳代码调用x86本地函数_C_Assembly_Code Injection_Shellcode - Fatal编程技术网

C 使用外壳代码调用x86本地函数

C 使用外壳代码调用x86本地函数,c,assembly,code-injection,shellcode,C,Assembly,Code Injection,Shellcode,我希望使用将流重定向到本地函数,然后使用外壳代码返回到原始函数 我定义了两个简单函数,并使用objdump获取它们的汇编代码: // unsigned char *g_code = "\x55\x48\x89\xe5\xb8\x2a\x00\x00\x00\x5d\xc3"; int g() { return 42; } // unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x

我希望使用将流重定向到本地函数,然后使用外壳代码返回到原始函数
我定义了两个简单函数,并使用objdump获取它们的汇编代码:

// unsigned char *g_code = "\x55\x48\x89\xe5\xb8\x2a\x00\x00\x00\x5d\xc3";
int g() {
    return 42;
}

// unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
int f() {
    int x = g();
    return 42;
}
在另一个文件中,我想在f的两条指令之间调用一个函数:

void redirect() {
    FILE *out = fopen("redirect.txt", "w");
    fprintf(out, "REDIRECT WORKED");
    fclose(out);
}
为此,我使用以下代码,使用-fPIC-fno stack protector-z execstack编译:

void f_func() {
    unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
    unsigned char f_code_modified[] = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\xfb\xfe\xff\xff\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";

    int value = 0;

    int (*f)() = (int (*)())f_code_modified;
    value = f();

    printf("%d\n", value);
}
如果我使用f的原始代码(正如我从objdump获得的),它就可以工作。 我想修改它以调用我的重定向函数,然后恢复当前的执行

装配代码(对于f_代码_修改):

0:55推ebp
eax年12月1日:48
2:89 e5 mov ebp,esp
eax年12月4日:48
5:83 ec 10子esp,0x10

8:b800 mov eax,0x0在Peter Cordes的评论之后,您可以将目标函数的绝对地址嵌入外壳代码中

要查找函数地址
redirect()
,我使用的是
nm
,因此命令是:

%nm | grep重定向

输出:
080484bb T重定向

因此,我重写您的外壳代码进行修改,添加了
redirect()
函数地址:

测试外壳代码

push ebp
dec eax
mov ebp,esp
dec eax
sub esp,0x10
mov eax,0x080484bb    ; redirect() function address
call eax
mov dword [ebp-0x4],eax
mov eax,dword [ebp-0x4]
leave
ret
push ebp
dec eax
mov ebp,esp
dec eax
sub esp,0x10
mov eax,0x80484bb    ; redirect() function address
call eax
mov eax,0x0
call 0x1c
mov dword [ebp-0x4],eax
mov eax,dword [ebp-0x4]
leave
ret
% ls -l
total 16
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:40 shell
-rw-rw-r-- 1 febri febri 1075 Jan  1 08:39 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% ./shell
0
% ls -l  
total 20
-rw-rw-r-- 1 febri febri   15 Jan  1 08:41 redirect.txt
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:40 shell
-rw-rw-r-- 1 febri febri 1075 Jan  1 08:39 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% cat redirect.txt
REDIRECT WORKED
测试外壳代码2

push ebp
dec eax
mov ebp,esp
dec eax
sub esp,0x10
mov eax,0x080484bb    ; redirect() function address
call eax
mov dword [ebp-0x4],eax
mov eax,dword [ebp-0x4]
leave
ret
push ebp
dec eax
mov ebp,esp
dec eax
sub esp,0x10
mov eax,0x80484bb    ; redirect() function address
call eax
mov eax,0x0
call 0x1c
mov dword [ebp-0x4],eax
mov eax,dword [ebp-0x4]
leave
ret
% ls -l
total 16
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:40 shell
-rw-rw-r-- 1 febri febri 1075 Jan  1 08:39 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% ./shell
0
% ls -l  
total 20
-rw-rw-r-- 1 febri febri   15 Jan  1 08:41 redirect.txt
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:40 shell
-rw-rw-r-- 1 febri febri 1075 Jan  1 08:39 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% cat redirect.txt
REDIRECT WORKED
在这里,我修改了您的代码:

#include <stdio.h>
#include <string.h>

void redirect() {
    FILE *out = fopen("redirect.txt", "w");
    fprintf(out, "REDIRECT WORKED");
    fclose(out);
}

void f_func() {
//    unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
//    unsigned char f_code_modified[] = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\xbb\x84\x04\x08\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";

// Here shellcode, I wrote :

    unsigned char *test_shellcode = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\xbb\x84\x04\x08\xff\xd0\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";

//    unsigned char *test_shellcode2 = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\xbb\x84\x04\x08\xff\xd0\xb8\x00\x00\x00\x00\xe8\xa3\x7f\xfb\xf7\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";

    int value = 0;

    int (*f)() = (int (*)())test_shellcode;
    value = f();

    printf("%d\n", value);
}

int main(int argc, char **argv) {
    f_func();
}
但是,如果我使用test\u shellcode2,我会得到
分段错误
,但这是工作:

% ls -l
total 16
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:46 shell
-rw-rw-r-- 1 febri febri 1076 Jan  1 08:46 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% ./shell
[1]    7465 segmentation fault (core dumped)  ./shell
% ls -l
total 20
-rw-rw-r-- 1 febri febri   15 Jan  1 08:46 redirect.txt
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:46 shell
-rw-rw-r-- 1 febri febri 1076 Jan  1 08:46 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% cat redirect.txt
REDIRECT WORKED                                                                                                                                                  % 

在您的案例中,
调用
指令使用相对于其位置的相对偏移量。当您将这段代码移动到其他位置时,它开始跳转到错误的位置。因此,您的呼叫需要另一个带有绝对地址的表单。请尝试调试。。。或者尝试使用二进制忍者的外壳代码编译器插件,您可以将目标函数的绝对地址嵌入外壳代码中。类似于
mov-eax,0x12345678
<代码>调用eax