forked from vdisasm/pe-image-for-delphi
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathPE.Parser.TLS.pas
115 lines (92 loc) · 2.31 KB
/
PE.Parser.TLS.pas
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
unit PE.Parser.TLS;
interface
uses
SysUtils,
PE.Common,
PE.Types,
PE.Types.Directories,
PE.Types.TLS,
PE.TLS;
type
TPETLSParser = class(TPEParser)
public
function Parse: TParserResult; override;
end;
implementation
uses
PE.Image;
{ TPETLSParser }
function TPETLSParser.Parse: TParserResult;
var
PE: TPEImage;
var
Dir: TImageDataDirectory;
TLSDir: TTLSDirectory;
AddressofCallbacks: TVA;
CurRVA, CallbackVA: uint64;
bRead: boolean;
begin
PE := TPEImage(FPE);
if not PE.DataDirectories.Get(DDIR_TLS, @Dir) then
exit(PR_OK);
if Dir.IsEmpty then
exit(PR_OK);
if not PE.SeekRVA(Dir.VirtualAddress) then
begin
PE.Msg.Write(SCategoryTLS, 'Incorrect directory RVA.');
exit(PR_ERROR);
end;
case PE.ImageBits of
32:
begin
bRead := PE.ReadEx(TLSDir.tls32, SizeOf(TLSDir.tls32));
AddressofCallbacks := TLSDir.tls32.AddressofCallbacks;
end;
64:
begin
bRead := PE.ReadEx(TLSDir.tls64, SizeOf(TLSDir.tls64));
AddressofCallbacks := TLSDir.tls64.AddressofCallbacks;
end;
else
exit(PR_ERROR);
end;
if not bRead then
begin
PE.Msg.Write(SCategoryTLS, 'Failed to read directory.');
exit(PR_ERROR);
end;
// Assign dir.
PE.TLS.Dir := TLSDir;
// Try to read callback addresses if available.
// It's ok if there's no callbacks.
if AddressofCallbacks = 0 then
exit(PR_OK);
if not PE.SeekVA(AddressofCallbacks) then
begin
PE.Msg.Write(SCategoryTLS, 'Incorrect address of callbacks.');
exit(PR_OK);
end;
while True do
begin
CurRVA := PE.PositionRVA;
// Try to read callback address.
if not PE.ReadWordEx(0, @CallbackVA) then
begin
PE.Msg.Write(SCategoryTLS, 'Failed to read callback address at RVA: 0x%x. Probably malformed data.', [CurRVA]);
break;
end;
// Is it terminator?
if CallbackVA = 0 then
break;
// Does the address exist?
if not PE.VAExists(CallbackVA) then
begin
PE.Msg.Write(SCategoryTLS, 'Bad callback address (0x%x) at RVA: 0x%x', [CallbackVA, CurRVA]);
break;
end;
// Add existing address.
PE.TLS.CallbackRVAs.Add(PE.VAToRVA(CallbackVA))
end;
exit(PR_OK);
end;
end.