Playing with ptrace 2.docx

上传人:b****1 文档编号:1357267 上传时间:2023-04-30 格式:DOCX 页数:16 大小:103.82KB
下载 相关 举报
Playing with ptrace 2.docx_第1页
第1页 / 共16页
Playing with ptrace 2.docx_第2页
第2页 / 共16页
Playing with ptrace 2.docx_第3页
第3页 / 共16页
Playing with ptrace 2.docx_第4页
第4页 / 共16页
Playing with ptrace 2.docx_第5页
第5页 / 共16页
Playing with ptrace 2.docx_第6页
第6页 / 共16页
Playing with ptrace 2.docx_第7页
第7页 / 共16页
Playing with ptrace 2.docx_第8页
第8页 / 共16页
Playing with ptrace 2.docx_第9页
第9页 / 共16页
Playing with ptrace 2.docx_第10页
第10页 / 共16页
Playing with ptrace 2.docx_第11页
第11页 / 共16页
Playing with ptrace 2.docx_第12页
第12页 / 共16页
Playing with ptrace 2.docx_第13页
第13页 / 共16页
Playing with ptrace 2.docx_第14页
第14页 / 共16页
Playing with ptrace 2.docx_第15页
第15页 / 共16页
Playing with ptrace 2.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Playing with ptrace 2.docx

《Playing with ptrace 2.docx》由会员分享,可在线阅读,更多相关《Playing with ptrace 2.docx(16页珍藏版)》请在冰点文库上搜索。

Playing with ptrace 2.docx

Playingwithptrace2

InPartIIofhisseriesonptrace,Pradeeptacklesthemoreadvancedtopicsofsettingbreakpointsandinjectingcodeintorunningprocesses.

InPartIofthisarticle[LJ,November2002],wesawhowptracecanbeusedtotracesystemcallsandchangesystemcallarguments.Inthisarticle,weinvestigateadvancedtechniqueslikesettingbreakpointsandinjectingcodeintorunningprograms.Debuggersusethesemethodstosetupbreakpointsandexecutedebugginghandlers.AswithPartI,allcodeinthisarticleisi386architecture-specific.

AttachingtoaRunningProcess

InPartI,werantheprocesstobetracedasachildaftercallingptrace(PTRACE_TRACEME,..).Ifyousimplywantedtoseehowtheprocessismakingsystemcallsandtracetheprogram,thiswouldbesufficient.Ifyouwanttotraceordebugaprocessalreadyrunning,thenptrace(PTRACE_ATTACH,..)shouldbeused.

Whenaptrace(PTRACE_ATTACH,..)iscalledwiththepidtobetraced,itisroughlyequivalenttotheprocesscallingptrace(PTRACE_TRACEME,..)andbecomingachildofthetracingprocess.ThetracedprocessissentaSIGSTOP,sowecanexamineandmodifytheprocessasusual.Afterwearedonewithmodificationsortracing,wecanletthetracedprocesscontinueonitsownbycallingptrace(PTRACE_DETACH,..).

Thefollowingisthecodeforasmallexampletracingprogram:

intmain()

{inti;

for(i=0;i<10;++i){

printf("Mycounter:

%d\n",i);

sleep

(2);

}

return0;

}

Savetheprogramasdummy2.c.Compileandrunit:

gcc-odummy2dummy2.c

./dummy2&

Now,wecanattachtodummy2byusingthecodebelow:

#include

#include

#include

#include

#include/*Foruser_regs_struct

etc.*/

intmain(intargc,char*argv[])

{pid_ttraced_process;

structuser_regs_structregs;

longins;

if(argc!

=2){

printf("Usage:

%s\n",

argv[0],argv[1]);

exit

(1);

}

traced_process=atoi(argv[1]);

ptrace(PTRACE_ATTACH,traced_process,

NULL,NULL);

wait(NULL);

ptrace(PTRACE_GETREGS,traced_process,

NULL,®s);

ins=ptrace(PTRACE_PEEKTEXT,traced_process,

regs.eip,NULL);

printf("EIP:

%lxInstructionexecuted:

%lx\n",

regs.eip,ins);

ptrace(PTRACE_DETACH,traced_process,

NULL,NULL);

return0;

}

Theaboveprogramsimplyattachestoaprocess,waitsforittostop,examinesitseip(instructionpointer)anddetaches.

Toinjectcodeuseptrace(PTRACE_POKETEXT,..)andptrace(PTRACE_POKEDATA,..)afterthetracedprocesshasstopped.

SettingBreakpoints

Howdodebuggerssetbreakpoints?

Generally,theyreplacetheinstructiontobeexecutedwithatrapinstruction,sothatwhenthetracedprogramstops,thetracingprogram,thedebugger,canexamineit.Itwillreplacetheoriginalinstructiononcethetracingprogramcontinuesthetracedprocess.Here'sanexample:

#include

#include

#include

#include

#include

constintlong_size=sizeof(long);

voidgetdata(pid_tchild,longaddr,

char*str,intlen)

{char*laddr;

inti,j;

unionu{

longval;

charchars[long_size];

}data;

i=0;

j=len/long_size;

laddr=str;

while(i

data.val=ptrace(PTRACE_PEEKDATA,child,

addr+i*4,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*4,NULL);

memcpy(laddr,data.chars,j);

}

str[len]='\0';

}

voidputdata(pid_tchild,longaddr,

char*str,intlen)

{char*laddr;

inti,j;

unionu{

longval;

charchars[long_size];

}data;

i=0;

j=len/long_size;

laddr=str;

while(i

memcpy(data.chars,laddr,long_size);

ptrace(PTRACE_POKEDATA,child,

addr+i*4,data.val);

++i;

laddr+=long_size;

}

j=len%long_size;

if(j!

=0){

memcpy(data.chars,laddr,j);

ptrace(PTRACE_POKEDATA,child,

addr+i*4,data.val);

}

}

intmain(intargc,char*argv[])

{pid_ttraced_process;

structuser_regs_structregs,newregs;

longins;

/*int0x80,int3*/

charcode[]={0xcd,0x80,0xcc,0};

charbackup[4];

if(argc!

=2){

printf("Usage:

%s\n",

argv[0],argv[1]);

exit

(1);

}

traced_process=atoi(argv[1]);

ptrace(PTRACE_ATTACH,traced_process,

NULL,NULL);

wait(NULL);

ptrace(PTRACE_GETREGS,traced_process,

NULL,®s);

/*Copyinstructionsintoabackupvariable*/

getdata(traced_process,regs.eip,backup,3);

/*Putthebreakpoint*/

putdata(traced_process,regs.eip,code,3);

/*Lettheprocesscontinueandexecute

theint3instruction*/

ptrace(PTRACE_CONT,traced_process,NULL,NULL);

wait(NULL);

printf("Theprocessstopped,puttingback"

"theoriginalinstructions\n");

printf("Presstocontinue\n");

getchar();

putdata(traced_process,regs.eip,backup,3);

/*Settingtheeipbacktotheoriginal

instructiontolettheprocesscontinue*/

ptrace(PTRACE_SETREGS,traced_process,

NULL,®s);

ptrace(PTRACE_DETACH,traced_process,

NULL,NULL);

return0;

}

Herewereplacethethreebyteswiththecodeforatrapinstruction,andwhentheprocessstops,wereplacetheoriginalinstructionsandresettheeiptooriginallocation.Figures1-4clarifyhowtheinstructionstreamlookswhenaboveprogramisexecuted.

Figure1.AftertheProcessIsStopped

Figure2.AftertheTrapInstructionBytesAreSet

Figure3.TrapIsHitandControlIsGiventotheTracingProgram

Figure4.AftertheOriginalInstructionsAreReplacedandeipIsResettotheOriginalLocation

Nowthatwehaveaclearideaofhowbreakpointsareset,let'sinjectsomecodebytesintoarunningprogram.Thesecodebyteswillprint“helloworld”.

Thefollowingprogramisasimple“helloworld”programwithmodificationstofitourneeds.Compilethefollowingprogramwith:

gcc-ohellohello.c

voidmain()

{

__asm__("

jmpforward

backward:

popl%esi#Gettheaddressof

#helloworldstring

movl$4,%eax#Dowritesystemcall

movl$2,%ebx

movl%esi,%ecx

movl$12,%edx

int$0x80

int3#Breakpoint.Herethe

#programwillstopand

#givecontrolbackto

#theparent

forward:

callbackward

.string\"HelloWorld\\n\""

);

}

Thejumpingbackwardandforwardhereisrequiredtofindtheaddressofthe“helloworld”string.

WecangetthemachinecodefortheaboveassemblyfromGDB.FireupGDBanddisassembletheprogram:

(gdb)disassemblemain

Dumpofassemblercodeforfunctionmain:

0x80483e0

:

push%ebp

0x80483e1:

mov%esp,%ebp

0x80483e3:

jmp0x80483fa

Endofassemblerdump.

(gdb)disassembleforward

Dumpofassemblercodeforfunctionforward:

0x80483fa:

call0x80483e5

0x80483ff:

dec%eax

0x8048400:

gs

0x8048401:

insb(%dx),%es:

(%edi)

0x8048402:

insb(%dx),%es:

(%edi)

0x8048403:

outsl%ds:

(%esi),(%dx)

0x8048404:

and%dl,0x6f(%edi)

0x8048407:

jb0x8048475

0x8048409:

or%fs:

(%eax),%al

0x804840c:

mov%ebp,%esp

0x804840e:

pop%ebp

0x804840f:

ret

Endofassemblerdump.

(gdb)disassemblebackward

Dumpofassemblercodeforfunctionbackward:

0x80483e5:

pop%esi

0x80483e6:

mov$0x4,%eax

0x80483eb:

mov$0x2,%ebx

0x80483f0:

mov%esi,%ecx

0x80483f2:

mov$0xc,%edx

0x80483f7:

int$0x80

0x80483f9:

int3

Endofassemblerdump.

Weneedtotakethemachinecodebytesfrommain+3tobackward+20,whichisatotalof41bytes.ThemachinecodecanbeseenwiththexcommandinGDB:

(gdb)x/40bxmain+3

:

eb155eb804000000

:

bb0200000089f1ba

:

0c000000cd80cc

:

e6ffffff48656c6c

:

6f20576f726c640a

Nowwehavetheinstructionbytestobeexecuted.Whywait?

Wecaninjectthemusingthesamemethodasinthepreviousexample.Thefollowingisthesourcecode;onlythemainfunctionisgivenhere:

intmain(intargc,char*argv[])

{pid_ttraced_process;

structuser_regs_structregs,newregs;

longins;

intlen=41;

charinsertcode[]=

"\xeb\x15\x5e\xb8\x04\x00"

"\x00\x00\xbb\x02\x00\x00\x00\x89\xf1\xba"

"\x0c\x00\x00\x00\xcd\x80\xcc\xe8\xe6\xff"

"\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f"

"\x72\x6c\x64\x0a\x00";

charbackup[len];

if(argc!

=2){

printf("Usage:

%s\n",

argv[0],argv[1]);

exit

(1);

}

traced_process=atoi(argv[1]);

ptrace(PTRACE_ATTACH,traced_process,

NULL,NULL);

wait(NULL);

ptrace(PTRACE_GETREGS,traced_process,

NULL,®s);

getdata(traced_process,regs.eip,backup,len);

putdata(traced_process,regs.eip,

insertcode,len);

ptrace(PTRACE_SETREGS,traced_process,

NULL,®s);

ptrace(PTRACE_CONT,traced_process,

NULL,NULL);

wait(NULL);

printf("Theprocessstopped,Puttingback"

"theoriginalinstructions\n");

putdata(traced_process,regs.eip,backup,len);

ptrace(PTRACE_SETREGS,traced_process,

NULL,®s);

printf("Lettingitcontinuewith"

"originalflow\n");

ptrace(PTRACE_DETACH,traced_process,

NULL,NULL);

return0;

InPartIIofhisseriesonptrace,Pradeeptacklesthemoreadvancedtopicsofsettingbreakpointsandinjectingcodeintorunningprocesses.

InjectingtheCodeintoFreeSpace

Inthepreviousexampleweinjectedthecodedirectlyintotheexecutinginstructionstream.However,debuggerscangetconfusedwiththiskindofbehaviour,solet'sfindthefreespaceintheprocessandinjectthecodethere.Wecanfindfreespacebyexaminingthe/proc/pid/mapsfileofthetr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2