-
Notifications
You must be signed in to change notification settings - Fork 25
/
rustbof.cna
74 lines (69 loc) · 2.32 KB
/
rustbof.cna
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
import pe.OBJExecutable;
import common.Packer;
alias rustbof {
local('$arch $handle $data $args $relocs');
$arch = binfo($1, "arch");
$handle = openf(script_resource("rustbof." . $arch. ".o"));
$data = readb($handle, -1);
$relocs = build_data_relocs($1, $data, "entrypoint");
if ($relocs is $null) {
berror($1, "Relocation packing failed");
return;
}
# the first args MUST be the relocation bytes
$args = bof_pack($1, "bzi", $relocs, "a string argument", 123);
blog($1, "Tasking with rust bof");
beacon_inline_execute($1, $data, "entrypoint", $args);
}
# $1 - beacon
# $2 - coffbytes
# $3 - entry
sub build_data_relocs {
local('$beacon $coff $parser $table $entry $packer');
($beacon, $coff, $entry) = @_;
$parser = [new OBJExecutable: $coff, $entry];
[$parser parse];
if ([$parser hasErrors]) {
berror($beacon, "Object file has errors: " . [$parser getErrors]);
return $null;
}
$packer = [new Packer];
[$packer little];
# .data relocations are done by CS as of 4.9... don't know when they added that
# let's just do .rdata
$nrdata = build_relocs_for_section($beacon, ".rdata", $parser, $packer);
if ($nrdata is $null) {
berror($beacon, "Failed to create relocs for .rdata");
return $null;
}
return [$packer getBytes];
}
# $1 - beacon
# $2 - secname
# $3 - parser
# $4 - packer
sub build_relocs_for_section {
local('$beacon $secname $parser $packer $reloc_count $reloc $objinfo $idx $sec_idx $relsec $sec_id');
($beacon, $secname, $parser, $packer) = @_;
$objinfo = [$parser getInfo];
$reloc_count = [$objinfo relocationsCount: $secname];
for ($idx = 0; $idx < $reloc_count; $idx++) {
$reloc = [$objinfo getRelocation: $secname, $idx];
$relsec = [$reloc getSection];
if (".text" eq $relsec) {
$sec_id = 1;
} else if (".data" eq $relsec) {
$sec_id = 2;
} else if (".rdata" eq $relsec) {
$sec_id = 3;
} else {
berror($beacon, "Unknown section: " . $relsec);
return $null;
}
[$packer addInt: [$reloc getOffsetInSection]];
[$packer addInt: [$reloc getOffset]];
[$packer addByte: $sec_id];
[$packer addByte: [$reloc getType]];
}
return $reloc_count;
}