Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add: dbg.libs/unlibs for linux #6567

Merged
merged 1 commit into from
Jan 24, 2017
Merged

Add: dbg.libs/unlibs for linux #6567

merged 1 commit into from
Jan 24, 2017

Conversation

leberus
Copy link
Contributor

@leberus leberus commented Jan 24, 2017

This commits adds internal breakpoints for dlopen, dlmopen and dlclose.
A proper return reason has been added in linux_dbg_wait , so when typing di we can see the reason.

Some things still have to be fixed:

  • it prints twice the command stored in bp->data.
    First it prints the first part of the string (before ";"), and when it does a rcons_flush it prints everything (this issue was already here but i'll take a look).
  • To know which library was unloaded more work should be done. We should keep a list of libraries like:

struct library {
ut64 handler;
char *name;
};

The handler field would be the value returned from dlopen/dlmopen (value in rax). Once r2 detects a dbg.unlibs, it should compare all handlers we got so far with the one we're gonna close with dlclose (value passed in rdi).

And then we could keep this list in a lib field within RDebug structure.
So every time we unload a library, we can also print its name.

oscar@oscar:~/lab/r2/3462$ r2 -d loadlib
[0x7f4662fe3190]> db
0x00400590 - 0x00400591 1 --x sw break enabled cmd="?e dbg.libs: sym.imp.dlopen;ps@r:rdi" cond="" name="" module=""
0x004005c0 - 0x004005c1 1 --x sw break enabled cmd="?e dbg.libs: sym.imp.dlmopen;ps@r:rsi" cond="" name="" module=""
0x004005a0 - 0x004005a1 1 --x sw break enabled cmd="?e dbg.unlibs: sym.imp.dlclose" cond="" name="" module=""
[0x7f4662fe3190]> dc
Selecting and continuing: 9125
hit breakpoint at: 400590
dbg.libs: sym.imp.dlopen

dbg.libs: sym.imp.dlopen
libgvc.so.6.0.0
[0x00400590]> dc
Selecting and continuing: 9125
hit breakpoint at: 4005a0
dbg.unlibs: sym.imp.dlclose
dbg.unlibs: sym.imp.dlclose
[0x00400590]> di
type=exit-lib
signal=SIGTRAP
signum=5
sigpid=9125
addr=0x0
bp_addr=0x4005a0
......
[0x00400590]> dc
Selecting and continuing: 9125
hit breakpoint at: 4005c0
dbg.libs: sym.imp.dlmopen

dbg.libs: sym.imp.dlmopen
libgvc.so.6.0.0
[0x00400590]> di
type=new-lib
signal=SIGTRAP
signum=5
sigpid=9125
addr=0x0
bp_addr=0x4005c0
....
[0x00400590]>

@@ -312,7 +312,13 @@ static bool setbpint(RCore *r, const char *mode, const char *sym) {
if (bp) {
bp->internal = true;
#if __linux__
bp->data = r_str_newf ("?e %s: %s;dd", mode, sym);
if (strncmp (sym, "sym.imp.dlclose", strlen ("sym.imp.dlclose"))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use r_str_startswith

if (strncmp (sym, "sym.imp.dlclose", strlen ("sym.imp.dlclose"))) {
bp->data = r_str_newf ("?e %s: %s;ps@r:%s", mode, sym,
!strncmp (sym, "sym.imp.dlmopen", strlen ("sym.imp.dlmopen"))
? "rsi" : "rdi");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not portable. r2 have a way to determine the value of the register depending on the purpose, rsi/rdi is only for x86-64, and core/file.c is not the place to put arch-specific things

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you tell me more about this way? is a function?

dbg->reason.type = R_DEBUG_REASON_BREAKPOINT;
dbg->reason.bp_addr = (ut64)siginfo.si_addr;
{
#if 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the if 1

char no_str[128];
char mode[128] = {0};

sscanf (b->data, "%s %s %s", no_str, mode, no_str);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can overflow

char mode[128] = {0};

sscanf (b->data, "%s %s %s", no_str, mode, no_str);
if (!strncmp (mode, "dbg.libs", strlen ("dbg.libs"))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use r_str_startswith

sscanf (b->data, "%s %s %s", no_str, mode, no_str);
if (!strncmp (mode, "dbg.libs", strlen ("dbg.libs"))) {
dbg->reason.type = R_DEBUG_REASON_NEW_LIB;
} else if (!strncmp (mode, "dbg.unlibs", strlen ("dbg.unlibs"))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}
}
#endif

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty line

@radare
Copy link
Collaborator

radare commented Jan 24, 2017 via email

@leberus
Copy link
Contributor Author

leberus commented Jan 24, 2017

well i guess i'll just put bp->data = r_str_newf ("?e %s: %s", mode, sym); on core/file.c , and i'll do all library investigation "stuff" on linux_debug.c

@leberus leberus force-pushed the 3462 branch 2 times, most recently from a064ab6 to a7680fa Compare January 24, 2017 14:11
@leberus
Copy link
Contributor Author

leberus commented Jan 24, 2017

I've fixed all other issues. I'll do the reg's stuff now.

@radare
Copy link
Collaborator

radare commented Jan 24, 2017

if you rebase, travis should be green again :3

@leberus
Copy link
Contributor Author

leberus commented Jan 24, 2017

I've rebased, but I'm still testing this on i386/arm/arm64

@radare
Copy link
Collaborator

radare commented Jan 24, 2017

travis doesnt tests the debugger, so that may not affect at all

//dlmopen passes library's name in esi
name = r_reg_get_name (dbg->reg, R_REG_NAME_A1);
}
snprintf (str, sizeof (str), ";ps@r:%s", name);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use r_str_concatf ?

if (dbg->glob_libs || dbg->glob_unlibs) {
ut64 pc_addr = r_debug_reg_get (dbg, "PC");
RBreakpointItem *b = r_bp_get_at (dbg->bp, pc_addr - dbg->bpsize);
if (b) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use if (b && b->internal) and reduce 1 level of indentation

@leberus
Copy link
Contributor Author

leberus commented Jan 24, 2017

I've fixed the comments.
Library detection is a bit tricky in i386 if the arguments are pushed into the stack and not passed to registers instead.
I'll try to figure out how can I get those arguments.

@radare radare merged commit 82f282c into radareorg:master Jan 24, 2017
@radare
Copy link
Collaborator

radare commented Jan 24, 2017

Awesome! :D didnt expected to have all this stuff ready before the release! now let's focus on testing and finish the pending issues before release. to be sure we are not breaking anything

Thanks!

@leberus
Copy link
Contributor Author

leberus commented Jan 24, 2017

Yap! Actually I'm planning to start writing some tests for the debugger, so we realize faster if something gets fucked up by our changes :)

@radare radare mentioned this pull request Jan 31, 2017
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants