drip43

b4nd1t

滴水逆向作业43

作业

1690263915677

步骤

实现文件到filebuffer到imagebuffer再到newbuffer再存盘

1.文件读取到内存获得filebuffer

2.在可选pe头中获得 SizeOfImage (DWORD)进行malloc,地址为e_ifanew + 4 + 0x14 + 0x38

3.拉伸前后头是不变的,先把头copy到内存中,大小为可选pe头中的sizeofheads(DWORD),地址为e_ifanew + 4 + 0x14 + 0x3c

4.在标准pe头中获得numberofsections(WORD),作为后来for循环的次数,地址为e_ifanew + 4 + 2

5.找到节表的起始地址 e_lfanew + 4 + 0x14 + SizeOfOptionalHeader ,SizeOfOptionalHeader(WORD)的地址为e_ifanew + 4 + 0x10

6.在节表中复制的源地址偏移为 PointerToRawData (DWORD) 0x14,目标地址偏移为 VirtualAddress (DWORD) 0x0c,大小为 SizeOfRawData (DWORD) 0x10

7.转换为filebuffer的时候相反

编写一个函数,能够将RVA的值转为FOA

1.通过for循环遍历每个节表判断在哪个节区

2.用PointerToRawData 加上相对于节的偏移

代码

一、

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
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
long n;
void* readtest()
{
FILE* fp = fopen("test32.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;
}
void* file2image(char* src)
{
unsigned int e_ifanew;
unsigned int sizeofimage;
unsigned int sizeofheads;
unsigned short numberofsections;
unsigned short sizeofoptionalheader;
int startsectiontable;
int i;
void* p;
e_ifanew = *(unsigned int*)(src + 0x3c);
printf("e_ifanew: 0x%x\n",e_ifanew);
sizeofimage = *(unsigned int*)(src + e_ifanew + 4 + 0x14 + 0x38);
printf("sizeofimage: 0x%x\n",sizeofimage);
p = malloc(sizeofimage);
if(p == NULL)
{
printf("failed\n");
exit(1);
}
memset(p,0x00,sizeofimage);
sizeofheads = *(unsigned int*)(src + e_ifanew + 4 + 0x14 + 0x3c);
printf("sizeofheads: 0x%x\n",sizeofheads);
memcpy(p,src,sizeofheads);
numberofsections = *(unsigned short*)(src + e_ifanew + 4 + 2);
printf("numberofsections: 0x%x\n",numberofsections);
sizeofoptionalheader = *(unsigned short*)(src + e_ifanew + 4 + 0x10);
printf("sizeofoptionalheader: 0x%x\n",sizeofoptionalheader);
startsectiontable = e_ifanew + 4 + 0x14 + sizeofoptionalheader;
printf("startsectiontable: 0x%x\n",startsectiontable);
for(i=0;i<numberofsections;i++)
{
unsigned int pointertorawdata;
unsigned int virtualaddress;
unsigned int sizeofrawdata;
pointertorawdata = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x14);
virtualaddress = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x0c);
sizeofrawdata = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x10);
memcpy(p + virtualaddress,src + pointertorawdata,sizeofrawdata);
}
printf("Successfully!\n");
return p;
}
void* image2file(char* src)
{
void* p;
p = malloc(n);
if(p == NULL)
{
printf("failed");
exit(0);
}
memset(p,0x00,n);
unsigned int e_ifanew;
unsigned int sizeofimage;
unsigned int sizeofheads;
unsigned short numberofsections;
unsigned short sizeofoptionalheader;
int startsectiontable;
int i;
e_ifanew = *(unsigned int*)(src + 0x3c);
printf("e_ifanew: 0x%x\n",e_ifanew);
sizeofheads = *(unsigned int*)(src + e_ifanew + 4 + 0x14 + 0x3c);
printf("sizeofheads: 0x%x\n",sizeofheads);
memcpy(p,src,sizeofheads);
numberofsections = *(unsigned short*)(src + e_ifanew + 4 + 2);
printf("numberofsections: 0x%x\n",numberofsections);
sizeofoptionalheader = *(unsigned short*)(src + e_ifanew + 4 + 0x10);
printf("sizeofoptionalheader: 0x%x\n",sizeofoptionalheader);
startsectiontable = e_ifanew + 4 + 0x14 + sizeofoptionalheader;
printf("startsectiontable: 0x%x\n",startsectiontable);
for(i=0;i<numberofsections;i++)
{
unsigned int pointertorawdata;
unsigned int virtualaddress;
unsigned int sizeofrawdata;
pointertorawdata = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x14);
virtualaddress = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x0c);
sizeofrawdata = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x10);
memcpy(p + pointertorawdata,src + virtualaddress,sizeofrawdata);
}
printf("Successfully!\n");
return p;
}
void writetest(char* src)
{
FILE* fp = fopen("newtest32.exe","wb");
fwrite(src,1,n,fp);
printf("Successfully!\n");
fclose(fp);
}
int main()
{
char* p1;
char* p2;
char* p3;
p1 = (char*)readtest();
p2 = (char*)file2image(p1);
p3 = (char*)image2file(p2);
writetest(p3);
return 0;
}

二、

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
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* readtest()
{
FILE* fp = fopen("test32.exe","rb");
long n;
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);
return p;
}
int rva2foa(char* src,int rva)
{
unsigned int e_ifanew;
unsigned short numberofsections;
unsigned short sizeofoptionalheader;
int startsectiontable;
int startsection;
int i;
e_ifanew = *(unsigned int*)(src + 0x3c);
numberofsections = *(unsigned short*)(src + e_ifanew + 4 + 2);
sizeofoptionalheader = *(unsigned short*)(src + e_ifanew + 4 + 0x10);
startsectiontable = e_ifanew + 4 + 0x14 + sizeofoptionalheader;
startsection = *(unsigned int*)(src + startsectiontable + 0x14);
if(rva < startsection)
{
return rva;
}
for(i=0;i<numberofsections;i++)
{
unsigned int pointertorawdata;
unsigned int virtualaddress;
unsigned int sizeofrawdata;
pointertorawdata = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x14);
virtualaddress = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x0c);
sizeofrawdata = *(unsigned int*)(src + startsectiontable + i*0x28 + 0x10);
if(rva>=virtualaddress && rva<=(virtualaddress + sizeofrawdata))
{
return pointertorawdata + rva - virtualaddress;
}
}
printf("error\n");
exit(1);
}
int main()
{
char* p;
int result;
p = (char*)readtest();
result = rva2foa(p,0x12000);
printf("0x%x\n",result);
return 0;
}