squid/backends/clang/
concretize.rs1use std::collections::HashMap;
2
3use crate::frontend::{
4 ao::Op,
5 ChunkContent,
6 FixedVec,
7 Pointer,
8 ProcessImage,
9 VAddr,
10};
11
12fn lookup_pointer(image: &ProcessImage, pointer: &Pointer, table: &mut HashMap<Pointer, VAddr>) {
13 if table.contains_key(pointer) {
14 return;
15 }
16
17 let addr = match pointer {
18 Pointer::Function(pointer) => {
19 let chunk = image
20 .elf(pointer.elf)
21 .unwrap()
22 .section(pointer.section)
23 .unwrap()
24 .symbol(pointer.symbol)
25 .unwrap()
26 .chunk(pointer.chunk)
27 .unwrap();
28
29 let ChunkContent::Code(func) = chunk.content() else { unreachable!() };
30 let entry = func.cfg().entry();
31
32 func.cfg().basic_block(entry).unwrap().vaddr().unwrap()
33 },
34 Pointer::BasicBlock(pointer) => {
35 let chunk = image
36 .elf(pointer.elf)
37 .unwrap()
38 .section(pointer.section)
39 .unwrap()
40 .symbol(pointer.symbol)
41 .unwrap()
42 .chunk(pointer.chunk)
43 .unwrap();
44
45 let ChunkContent::Code(func) = chunk.content() else { unreachable!() };
46
47 func.cfg().basic_block(pointer.bb).unwrap().vaddr().unwrap()
48 },
49 Pointer::Global(pointer) => {
50 let addr = image
51 .elf(pointer.elf)
52 .unwrap()
53 .section(pointer.section)
54 .unwrap()
55 .symbol(pointer.symbol)
56 .unwrap()
57 .chunk(pointer.chunk)
58 .unwrap()
59 .vaddr();
60 addr + pointer.offset as VAddr
61 },
62 Pointer::Null => 0,
63 };
64
65 table.insert(pointer.clone(), addr);
66}
67
68pub(crate) fn concretize(image: &mut ProcessImage) {
69 let mut table = HashMap::<Pointer, VAddr>::new();
70
71 for elf in image.iter_elfs() {
73 for section in elf.iter_sections() {
74 for symbol in section.iter_symbols() {
75 for chunk in symbol.iter_chunks() {
76 match chunk.content() {
77 ChunkContent::Pointer(pointer) => {
78 lookup_pointer(image, pointer, &mut table);
79 },
80 ChunkContent::Code(func) => {
81 for bb in func.cfg().iter_basic_blocks() {
82 for op in bb.ops() {
83 if let Op::LoadPointer {
84 pointer,
85 ..
86 } = op
87 {
88 lookup_pointer(image, pointer, &mut table);
89 }
90 }
91 }
92 },
93 ChunkContent::Data {
94 ..
95 } => {},
96 }
97 }
98 }
99 }
100 }
101
102 for elf in image.iter_elfs_mut() {
104 for section in elf.iter_sections_mut() {
105 let perms = section.perms();
106
107 for symbol in section.iter_symbols_mut() {
108 for chunk in symbol.iter_chunks_mut() {
109 match chunk.content_mut() {
110 ChunkContent::Pointer(pointer) => {
111 let addr = *table.get(pointer).unwrap();
112 let bytes = FixedVec::lock(addr.to_le_bytes());
113 let perms = FixedVec::lock(vec![perms; bytes.len()]);
114 chunk.set_content(ChunkContent::Data {
115 bytes,
116 perms,
117 });
118 },
119 ChunkContent::Code(func) => {
120 for bb in func.cfg_mut().iter_basic_blocks_mut() {
121 bb.set_cursor(0);
122
123 while let Some(op) = bb.cursor_op() {
124 if let Op::LoadPointer {
125 dst,
126 pointer,
127 } = op
128 {
129 let vaddr = *table.get(pointer).unwrap();
130 bb.replace_op(Op::LoadVirtAddr {
131 dst: *dst,
132 vaddr,
133 });
134 }
135
136 if !bb.move_cursor_forward() {
137 break;
138 }
139 }
140 }
141 },
142 ChunkContent::Data {
143 ..
144 } => {},
145 }
146 }
147 }
148 }
149 }
150}