drip51

b4nd1t

滴水逆向作业51

要求

将一个dll文件的imagebase改掉,写代码模拟重定位操作,使dll文件可以正常使用

代码

操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
long n;
unsigned int elfanew;
unsigned int sizeofimage;
unsigned int sizeofheads;
unsigned short numberofsections;
unsigned short sizeofoptionalheader;
int startsectiontable;
void* dllread()
{
FILE* fp = fopen("mydll.dll","rb"); //此时的mydll.dll文件已经被修改了imagebase,相比之前增加了0x100000
void* p;
if(fp == NULL)
{
printf("failed");
exit(0);
}
fseek(fp,0,2);
n = ftell(fp);
p = malloc(n);
if(p == NULL)
{
printf("failed");
exit(0);
}
fseek(fp,0,0);
fread(p,1,n,fp);
fclose(fp);
return p;
}
int rva2foa(char* p,int rva)
{
int i;
if(rva<=sizeofheads)
{
return rva;
}
for(i=0;i<numberofsections;i++)
{
int va = *(int*)(p + startsectiontable + i*0x28 + 0xc);
int sord = *(int*)(p + startsectiontable + i*0x28 + 0x10);
int ptrd = *(int*)(p + startsectiontable + i*0x28 + 0x14);
if(rva>=va && rva<=va+sord)
{
return ptrd + (rva - va);
}
}
printf("error");
exit(1);
}
void writedll(char* p)
{
FILE* fp = fopen("newmydll.dll","wb");
if(fp == NULL)
{
printf("failed\n");
exit(1);
}
fwrite(p,1,n,fp);
}
int main()
{
char* p;
int relocrva;
int relocfoa;
int size;
int i;
p = (char*)dllread();
elfanew = *(unsigned int*)(p + 0x3c);
sizeofheads = *(unsigned int*)(p + elfanew + 4 + 0x14 + 0x3c);
numberofsections = *(unsigned short*)(p + elfanew + 4 + 2);
sizeofoptionalheader = *(unsigned short*)(p + elfanew + 4 + 0x10);
startsectiontable = elfanew + 4 + 0x14 + sizeofoptionalheader;
relocrva = *(unsigned int*)(p + elfanew + 4 + 0x14 + 0x60 + 5*0x8);
relocfoa = rva2foa(p,relocrva);
size = *(int*)(p + relocfoa + 4);
while(size != 0)
{
//*(int*)(p + relocfoa) += 0x1000;

int i;
for(i=0;i<((size-8)/2);i++)
{
int relocaddr = relocfoa + 8;
unsigned short item = *(unsigned short*)(p + relocaddr + i*2);
if(item >> 12 == 3)
{
unsigned int desaddr = rva2foa(p,*(unsigned int*)(p + relocfoa) + (item&0x0fff));
printf("0x%x\n",desaddr);
*(unsigned int*)(p + desaddr) += 0x100000;
}
}
printf("\n");
relocfoa += size;
size = *(int*)(p + relocfoa + 4);
}
writedll(p);
printf("success\n");
return 0;
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
#include<Windows.h>
int main()
{
HMODULE hDLL = LoadLibrary("newmydll.dll");
if(hDLL == NULL)
{
printf("error\n");
exit(1);
}
void (*fun)();
fun = (void (*)())GetProcAddress(hDLL,"show");
fun();
return 0;
}