drip55

b4nd1t

滴水逆向作业55

要求

代码实现导入表注入

代码

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
long n;
unsigned int elfanew;
unsigned int sizeofheads;
unsigned short numberofsections;
unsigned short sizeofoptionalheader;
int startsectiontable;
void* readpe()
{
FILE* fp = fopen("fg.exe","rb");
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("error1");
exit(1);
}
int foa2rva(char* p,int foa)
{
int i;
if(foa<=sizeofheads)
{
return foa;
}
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(foa>=ptrd && foa<=ptrd+sord)
{
return va + (foa - ptrd);
}
}
printf("error2");
exit(1);
}
char* editsec(char* p,int addsize)
{
char* newp;
newp = (char*)realloc(p,n + addsize);
*(int*)(newp + elfanew + 4 + 0x14 + 0x38) += 0x1000; //修改sizeofimage
*(int*)(newp + startsectiontable + 3*0x28 + 0x8) += 0x1000; //修改misc
*(int*)(newp + startsectiontable + 3*0x28 + 0x10) += 0x1000; //修改sizeofrawdata
*(int*)(newp + startsectiontable + 3*0x28 + 0x24) = 0xC0000040; //修改了节的characteristic
printf("添加成功\n");
return newp;
}
void movimport(char* p)
{
int numberofdll = 0;
int importtable;
int importtablefoa;
importtable = *(int*)(p + elfanew + 4 + 0x14 + 0x60 + 1*0x8);
importtablefoa = rva2foa(p,importtable);
int i;
for(i=0;;i++)
{
if(*(int*)(p + importtablefoa + i*0x14))
{
numberofdll++;
}
else
{
break;
}
}
printf("导入了%d个dll\n",numberofdll);
memset(p + n,0x00,0x1000);
memcpy(p + n,p + importtablefoa,numberofdll*0x14);
*(int*)(p + elfanew + 4 + 0x14 + 0x60 + 1*0x8) = foa2rva(p,n); //修改表项中的rva
*(int*)(p + elfanew + 4 + 0x14 + 0x60 + 1*0x8 + 4) = 0xf0;
//后面会用到0x28 + 0x8 + 0x8 + 0xa strlen("mydll.dll\x00") + 2 + strlen(name) 两个INT项,两个IAT项,一个name 一个函数名
*(unsigned int*)(p + n + numberofdll*0x14) = foa2rva(p,n + numberofdll*0x14 + 0x28); //设置INT的rva
*(unsigned int*)(p + n + numberofdll*0x14 + 0x4) = 0; //设置时间戳为0
*(unsigned int*)(p + n + numberofdll*0x14 + 0x8) = 0;
*(unsigned int*)(p + n + numberofdll*0x14 + 0xc) = foa2rva(p,n + numberofdll*0x14 + 0x28 + 0x8 + 0x8); //设置dllname地址
*(unsigned int*)(p + n + numberofdll*0x14 + 0x10) = foa2rva(p,n + numberofdll*0x14 + 0x28 + 0x8); //设置IAT
*(unsigned int*)(p + n + numberofdll*0x14 + 0x28) = foa2rva(p,n + numberofdll*0x14 + 0x28 + 0x8 + 0x8 + 0xa);
*(unsigned int*)(p + n + numberofdll*0x14 + 0x28 + 0x8) = foa2rva(p,n + numberofdll*0x14 + 0x28 + 0x8 + 0x8 + 0xa);
*(unsigned short*)(p + n + numberofdll*0x14 + 0x28 + 0x8 + 0x8 + 0xa) = 0x22;
strcpy(p + n + numberofdll*0x14 + 0x28 + 0x8 + 0x8,"mydll.dll");
strcpy(p + n + numberofdll*0x14 + 0x28 + 0x8 + 0x8 + 0xa + 2,"show");
}
void writepe(char* p)
{
FILE* fp = fopen("newfg.exe","wb");
fwrite(p,1,n + 0x1000,fp);
printf("成功写入\n");
}
int main()
{
char* p;
p = (char*)readpe();
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;
//修改最后一个节的大小,直接加上0x1000字节
p = editsec(p,0x1000);
//移动导入表到最后一个节
movimport(p);
//写入文件
writepe(p);
return 0;
}

效果

1691335180872

在dll文件中添加了初始化的弹窗,当双击新的fg时可以弹出此窗口

遇到的坑

我是直接扩大了最后一个节,然后将导入表移动到最后一个节,完成后一直不成功,然后我把最后一个节的Characteristic改成了导入表本来所在节的Characteristic,这样才可以成功运行。