简体   繁体   English

使用ptrace反转ls读数似乎不起作用

[英]Using ptrace to reverse ls readout doesn't seem to work

I've been following some instructions on how to use ptrace that are found here . 我一直在遵循一些有关如何使用ptrace的说明,这些说明可在此处找到。 I am on ubuntu 14.04, x64, and I have been altering bits of the example code to work with my x64 machine, such as eax to rax, and changing 4s to 8s where appropriate. 我使用的是Ubuntu 14.04,x64,并且我一直在更改示例代码以与x64机器一起使用,例如eax到rax,并在适当的地方将4s更改为8s。 The forth example is supposed to reverse the output of ls, but it does not. 第四个示例应该反转ls的输出,但不会。 I get this: 我得到这个:

bin       Debugger.depend  dummy1.s       main_tut2.cpp  main_tut4.cpp  obj
Debugger.cbp  Debugger.layout  main_tut1.cpp  main_tut3.cpp  main_tut5.cpp
bin       Debugger.depend  dummy1.s       main_tut2.cpp  main_tut4.cpp  obj
Debugger.cbp  Debugger.layout  main_tut1.cpp  main_tut3.cpp  main_tut5.cpp

And I believe I should be getting it reversed if my code works correctly, something like this: 而且我相信,如果我的代码正常工作,我应该将其恢复过来,就像这样:

jbo ppc.4tut_niam ppc.2tut_niam s.1ymmud dneped.reggubeD nib
ppc.5tut_niam ppc.3tut_niam ppc.1tut_niam tuoyal.reggubeD pbc.reggubeD
jbo ppc.4tut_niam ppc.2tut_niam s.1ymmud dneped.reggubeD nib
ppc.5tut_niam ppc.3tut_niam ppc.1tut_niam tuoyal.reggubeD pbc.reggubeD

I have found an error in the code printed in the page I linked above ( here ) which is 20 lines up from the bottom in my code, but I think I have corrected that. 我在上面链接的页面( 此处 )中打印的代码中发现一个错误,该错误比我的代码底部高20行,但是我认为我已纠正了该错误。 This is the incorrect line: 这是不正确的行:

                str = (char *)calloc((params[2] + 1) * sizeof(char));

It has one arguement but needs two. 它有一个论点,但需要两个。 I believe it should be: 我认为应该是:

                str = (char *)calloc(params[2] + 1, (params[2] + 1) * sizeof(char));

But if I have that wrong, I would be happy to be corrected. 但是,如果我错了,我很乐意得到纠正。 I also tried: 我也尝试过:

                str = (char *)calloc(1, (params[2] + 1) * sizeof(char));

I'm still not sure which would be correct, if either... 我仍然不确定哪一个是正确的...

Is this the reason why it's not working? 这是为什么它不起作用的原因吗? Or is it something else, maybe another problem relating to being on x64 that I haven't accounted for? 还是其他问题,也许是我尚未考虑的与安装在x64上有关的另一个问题? Bonus points for anyone who can tell me what calloc is doing in this instance and why the second arguement is as it is. 任何可以告诉我calloc在这种情况下在做什么以及为什么第二个争论仍然如此的人的奖励积分。

EDIT: 编辑:

I have just tried printing str both before and after the reversal... it's just a bunch of question marks. 我在反转前后都尝试过打印str ...这只是一堆问号。 When I debug, it seems the entire contents of str is -1s. 当我调试时,似乎str的全部内容是-1s。 This further suggests that something is wrong with my call to calloc()... 这进一步表明我对calloc()的调用有问题...

Anyway, here is my version of the code: 无论如何,这是我的代码版本:

#include <iostream>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>         // For fork()
//#include <linux/user.h>   // For constants ORIG_EAX for 32bit etc
#include <sys/user.h>       // For constants ORIG_RAX for 64bit etc
#include <sys/reg.h>
#include <sys/syscall.h>    // For SYS_write etc
#include <cstring>          // For strlen()

/** ptrace(enum __ptrace_request,   // behaviour of ptrace
           pid_t pid,               // Process ID
           void *addr,              // Address to read in user area
           void *data);             //
**/

/**
PTRACE_TRACEME,   PTRACE_PEEKTEXT, PTRACE_PEEKDATA, PTRACE_PEEKUSER,   PTRACE_POKETEXT,
PTRACE_POKEDATA,  PTRACE_POKEUSER, PTRACE_GETREGS,  PTRACE_GETFPREGS,  PTRACE_SETREGS,
PTRACE_SETFPREGS, PTRACE_CONT,     PTRACE_SYSCALL,  PTRACE_SINGLESTEP, PTRACE_DETACH
**/

const int long_size = sizeof(long);

void reverse(char *str) {

    int i, j;
    char temp;

    for (i = 0, j = strlen(str) - 2; i <= j; i++, j--) {
        temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
}

void getData(pid_t child, long addr, char *str, int len) {

    char *laddr;
    int i, j;
    union u {
        long val;
        char chars[long_size];
    } data;

    i = 0;
    j = len / long_size;
    laddr = str;

    while(i < j) {
        data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 8, NULL);
        memcpy(laddr, data.chars, long_size);
        i++;
        laddr += long_size;
    }

    j = len % long_size;

    if (j != 0) {
        data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 8, NULL);
        memcpy(laddr, data.chars, j);
    }

    str[len] = '\0';
}

void putData(pid_t child, long addr, char *str, int len) {

    char *laddr;
    int i, j;
    union u {
        long val;
        char chars[long_size];
    } data;

    i = 0;
    j = len / long_size;
    laddr = str;

    while(i < j) {
        memcpy(data.chars, laddr, long_size);
        ptrace(PTRACE_POKEDATA, child, addr + i * 8, data.val);
        i++;
        laddr += long_size;
    }

    j = len % long_size;

    if (j != 0) {
        memcpy(data.chars, laddr, j);
        ptrace(PTRACE_POKEDATA, child, addr + i * 8, data.val);
    }
}

int main()
{
    pid_t child;
    child = fork();

    if (child == 0) {

        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);

    } else {

        long orig_rax;
        long params[3];
        int status;
        char *str, *laddr;
        int toggle = 0;

        while(1) {

            wait(&status);
            if (WIFEXITED(status))
                break;

            orig_rax = ptrace(PTRACE_PEEKUSER, child, 8 * ORIG_RAX, NULL);

            if (orig_rax == SYS_write) {

                if (toggle == 0) {

                    toggle = 1;
                    params[0] = ptrace(PTRACE_PEEKUSER, child, 8 * RBX, NULL);
                    params[1] = ptrace(PTRACE_PEEKUSER, child, 8 * RCX, NULL);
                    params[2] = ptrace(PTRACE_PEEKUSER, child, 8 * RDX, NULL);
                    str = (char *)calloc(params[2] + 1, (params[2] + 1) * sizeof(char));

                    getData(child, params[1], str, params[2]);
                    reverse(str);
                    putData(child, params[1], str, params[2]);

                } else {

                    toggle = 0;
                }
            }

            ptrace(PTRACE_SYSCALL, child, NULL, NULL);
        }
    }

    execl("/bin/ls", "ls", NULL);

    return 0;
}

Any assistance would be greatly appreciated! 任何帮助将不胜感激!

So thanks to @melpmene and @MarkPlotnick for the answers. 因此,感谢@melpmene和@MarkPlotnick的回答。 I have struggled to figure out some of the other answers covering the same topic, and another resource I found that suggested how to convert the x32 code to x64 code wasn't entirely accurate (at least for my system), so here is what I needed to do: 我一直在努力找出涉及同一主题的其他一些答案,而我发现的另一个资源表明如何将x32代码转换为x64代码并不完全准确(至少对于我的系统而言),所以这就是我需要做的:

1) 1)

str = (char *)calloc(params[2] + 1 * sizeof (char))

should be 应该

str = (char *)calloc(params[2] + 1, sizeof (char))

2) 2)

EBX, ECX and EDX should be replaced by RDI, RSI and RDX EBX,ECX和EDX应替换为RDI,RSI和RDX

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM