-
Notifications
You must be signed in to change notification settings - Fork 2
/
RELOCS.CPP
158 lines (145 loc) · 6.11 KB
/
RELOCS.CPP
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/************************************************************************
* relocs.cpp *
* This class maintains a list of relocation items from the exe file. *
* Borg keeps a list of any items which have been or should be relocated *
* when an executable is loaded. The class includes functions to *
* maintain the list including loading and saving to a database file, *
* and including relocating the image in memory when the database and *
* the file are reloaded. *
* The main reason for doing this is that during disassembly we can gain *
* additional information by knowing that a certain location is *
* relocated on file load. For example with an instruction like *
* mov eax,400000h, if the location containing 400000h is a relocation *
* item then we know that 400000h is an offset, and so we can *
* immediately rewrite it as mov eax, offset 400000h *
************************************************************************/
#include <windows.h>
#include "relocs.h"
#include "data.h"
#include "debug.h"
#include "dasm.h"
/************************************************************************
* constructor function *
************************************************************************/
relocs::relocs()
{ sizeofitem=sizeof(relocitem);
}
/************************************************************************
* destructor function *
* - currently null *
************************************************************************/
relocs::~relocs()
{
}
/************************************************************************
* addreloc *
* - adds a reloc item to the list of relocs *
* - a reloc item consists of only a location which is in the reloc *
* table, and a type for the relocation *
************************************************************************/
void relocs::addreloc(lptr loc,reloctype type)
{ relocitem *newname;
newname=new relocitem;
newname->addr=loc;
newname->type=type;
addto(newname);
#ifdef DEBUG
DebugMessage("Added Reloc : %04lx:%04lx",loc.segm,loc.offs);
#endif
}
/************************************************************************
* isreloc *
* - this is the function used throughout the disassembly engine to see *
* if somewhere was relocated. It returns true if the location is in *
* the table *
************************************************************************/
bool relocs::isreloc(lptr loc)
{ relocitem checkit,*findit;
checkit.addr=loc;
findit=find(&checkit);
if(findit!=NULL)
if(findit->addr==loc)
return true;
return false;
}
/************************************************************************
* the compare function for the reloc items *
* - relocs are sorted by location *
************************************************************************/
int relocs::compare(relocitem *i,relocitem *j)
{ if(i->addr==j->addr)
return 0;
if(i->addr>j->addr)
return 1;
return -1;
}
/************************************************************************
* relocfile *
* - this should be called after loading a database file. It goes *
* through all of the relocs and relocates the file again since when *
* we load a database we simply load the file image and do not work *
* our way through the whole file format again. *
************************************************************************/
bool relocs::relocfile(void)
{ dsegitem *ds;
relocitem *ri;
resetiterator();
ri=nextiterator();
while(ri!=NULL)
{ // relocate item.
ds=dta.findseg(ri->addr);
if(ds!=NULL) // changed in build 14, used to return false if not found
{ switch(ri->type)
{ case RELOC_NONE:
break;
case RELOC_SEG:
((word *)(&(ds->data[ri->addr.offs-ds->addr.offs])))[0]+=options.loadaddr.segm;
break;
case RELOC_OFFS16:
break;
case RELOC_OFFS32:
break;
case RELOC_SEGOFFS16:
break;
case RELOC_SEGOFFS32:
break;
default:
return false;
}
}
ri=nextiterator();
}
return true;
}
/************************************************************************
* newitem *
* - returns a pointer to a new relocitem, only used by database load *
************************************************************************/
relocitem *relocs::newitem(void)
{ return (new relocitem);
}
/************************************************************************
* write_item *
* - writes a reloc item to the savefile specified *
* uses the current item, and moves the iterator on *
************************************************************************/
bool relocs::write_item(savefile *sf)
{ relocitem *currdec;
currdec=nextiterator();
if(!sf->swrite(currdec,sizeof(relocitem)))
return false;
return true;
}
/************************************************************************
* read_item *
* - reads a reloc item from the savefile specified *
************************************************************************/
bool relocs::read_item(savefile *sf)
{ dword num;
relocitem *currdec;
currdec=new relocitem;
if(!sf->sread(currdec,sizeof(relocitem),&num))
return false;
addto(currdec);
return true;
}