实验内容
修改补充phase5.o重定位节中被清零的重定位记录,使其与main.o链接后能够正确输出学号编码后的字符串: $ gcc -o linkbomb main.o phase5.o $ ./linkbomb $学号编码后字符串
实验提示
仅需修改重定位节的内容。 不允许修改.text节内容。
给出的C代码
const int TRAN_ARRAY[] = {… …}; // 通过反汇编代码+重定位表,得知此数组真实名字叫fEgeEF
const char FDICT[] = FDICTDAT;
char BUF[] = MYID;
char CODE = PHASE5_COOKIE;
int transform_code( int code, int mode ) {
switch( TRAN_ARRAY [mode] & 0x00000007 ) {
case 0:
code = code & (~ TRAN_ARRAY[mode]);
break;
case 1:
code = code ^ TRAN_ARRAY[mode];
break;
… …
}
return code;
}
void generate_code( int cookie ) {
int i;
CODE = cookie;
for( i=0; i<sizeof(TRAN_ARRAY)/sizeof(int); i++ )
CODE = transform_code( CODE, i );
}
int encode( char* str ) {
int i, n = strlen(str);
for( i=0; i<n; i++ ) {
str[i] = (FDICT[str[i]] ^ CODE) & 0x7F;
if( str[i]<0x20 || str[i]>0x7E ) str[i] = ' ';
}
return n;
}
void do_phase() {
generate_code(PHASE5_COOKIE);
encode(BUF);
printf("%s\n", BUF);
}
粗略分析
重定位表
符号表
完全会写重定位表之后,去phase5.s中看哪些重定位的地方被抹去了
找到被抹去的地方(8个)
9处
对应C代码: switch( TRAN_ARRAY [mode] & 0x00000007 ) 中的 TRAN_ARRAY [xxx]、
重定位到:fEgeEF(9)
3d处
对应C代码: case=3的情况(C代码没有给出,但根据上下文可知道类似)
重定位到:fEgeEF(9)
【注意】不是看见一串可疑的00 00 00 00、ffffffff 就是要重定位,要对照C代码的。有时候人家就是要给局部变量清零,那显然不是重定位。比如92处,明显是个循环变量,对应C代码为 for( i=0; i<sizeof(TRAN_ARRAY)/sizeof(int); i++ )中的i=0
还有dc处也是循环变量
9b处
对应C代码: transform_code( CODE, i ); 将code给ax
重定位到:CODE(12)
a7处
对应C:调用 transform_code( CODE, i );
重定位到: transform_code(13)
fb处
str[i] = (FDICT[str[i]] ^ CODE) & 0x7F;中的FDICT(真实名字:qbivHB)(10)
102处
str[i] = (FDICT[str[i]] ^ CODE) & 0x7F;中的
CODE(12)
163处
C:调用encode(BUF); 调用函数,应该是PC相对寻址
重定位到:encode(PC相对)(15)
16e处
C:把BUF的首地址压栈传参(C代码是printf("%s\n", BUF); )(疑问,为什么源代码是printf,汇编之后就成了puts)传递数据,应该是绝对寻址
重定位到:BUF(绝对)(11)
补全.rel.text
重定位节从0x524开始。用hexedit打开phase5.o
改写
每个重定位条目由8字节组成。
前4字节:代码位置。
后4字节:寻址方式(01或02)在符号表的编号 00 00
改成这样↓
结束