Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: syzygy/experimental/protect/protect_unittest/integrity_check_transform_unittests.cc

Issue 2535563002: Added all code for integrity check transform (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "syzygy/experimental/protect/protect_lib/integrity_check_transform.h"
16
17 #include <sstream>
18 #include <map>
19
20 #include "gtest/gtest.h"
21 #include "syzygy/block_graph/basic_block.h"
22 #include "syzygy/block_graph/basic_block_assembler.h"
23 #include "syzygy/block_graph/basic_block_decomposer.h"
24 #include "syzygy/block_graph/basic_block_subgraph.h"
25 #include "syzygy/block_graph/block_graph.h"
26 #include "syzygy/block_graph/block_util.h"
27 #include "syzygy/block_graph/typed_block.h"
28 #include "syzygy/common/indexed_frequency_data.h"
29 #include "syzygy/instrument/transforms/unittest_util.h"
30
31 namespace protect {
32 namespace {
33
34 //using base::DictionaryValue;
35 //using base::ListValue;
36 //using base::Value;
37
38 using block_graph::BasicBlock;
39 using block_graph::BasicBlockDecomposer;
40 using block_graph::BasicBlockSubGraph;
41 using block_graph::BasicCodeBlock;
42 using block_graph::BlockGraph;
43 using block_graph::Instruction;
44
45 //typedef AllocationFilterTransform::Offset Offset;
46 //typedef AllocationFilterTransform::OffsetSet OffsetSet;
47 //typedef AllocationFilterTransform::FunctionNameOffsetMap
48 // FunctionNameOffsetMap;
49
50 static wchar_t kConfigBadPathDoesNotExist[] =
51 L"syzygy/instrument/test_data/"
52 L"allocation-filter-bad-path-does-not-exist.json";
53
54 class TestIntegrityCheckTransform : public IntegrityCheckTransform {
55 public:
56 //using IntegrityCheckTransform::pre_call_hook_ref_;
57 //using AllocationFilterTransform::post_call_hook_ref_;
58 using IntegrityCheckTransform::target_names_;
59 using IntegrityCheckTransform::partition_unit_map_;
60 using IntegrityCheckTransform::label_name_to_block_;
61 using IntegrityCheckTransform::dll_id_to_block_reference_;
62 using IntegrityCheckTransform::nr_pc_relative_refs_;
63 using IntegrityCheckTransform::is_bb_checked_map_;
64 using IntegrityCheckTransform::ic_block_chunk_index_map_;
65 using IntegrityCheckTransform::ic_block_reference_free_chunks;
66 using IntegrityCheckTransform::ic_chunk_checker_to_checkee_map_;
67 using IntegrityCheckTransform::precomputed_hashes_;
68 using IntegrityCheckTransform::checker_to_checkee_map_;
69 using IntegrityCheckTransform::xhash_block_;
70 using IntegrityCheckTransform::hash_block_;
71 using IntegrityCheckTransform::response_block_;
72 using IntegrityCheckTransform::id_to_label_;
73 using IntegrityCheckTransform::basic_block_sizes_;
74 using IntegrityCheckTransform::num_chunks_per_block;
75 using IntegrityCheckTransform::GetHashBlock;//done mohsen
76 using IntegrityCheckTransform::SetHashBlock;//done mohsen
77 using IntegrityCheckTransform::CheckHash;//done mohsen
78 using IntegrityCheckTransform::FixPrecomputedHashes;//done mohsen
79 using IntegrityCheckTransform::PatchPrecomputedHashes;//mohsen
80 using IntegrityCheckTransform::PatchBlockReference;//done mohsen
81 using IntegrityCheckTransform::RecomputeXorChunks;//done mohsen
82 using IntegrityCheckTransform::RecomputePivot;//done mohsen
83 using IntegrityCheckTransform::ComputeAggregatedChunksHash;//done mohsen
84 using IntegrityCheckTransform::ComputeAggregatedBlocksHash;//done mohsen
85 using IntegrityCheckTransform::PatchPivot;//done mohsen
86 using IntegrityCheckTransform::PatchBlockReferencesAndSizes;//done mohsen
87 using IntegrityCheckTransform::AddChunkIntegrityCheckCode;//done mohsen
88 using IntegrityCheckTransform::AddIntegrityCheckCode;//done mohsen
89 using IntegrityCheckTransform::ComputeChunks;//done mohsen
90 using IntegrityCheckTransform::AddChunkIntoIndexMap;//done mohsen
91 using IntegrityCheckTransform::GenerateChunkCombinations;//mohsen
92 using IntegrityCheckTransform::GetChunkUniqueKey;//done mohsen
93 using IntegrityCheckTransform::PrecomputeHash;
94 using IntegrityCheckTransform::IsIdInPartitionUnitMap;
95 using IntegrityCheckTransform::GenerateLabelToBlockMap;
96 using IntegrityCheckTransform::UpdateLabelToBlockMap;
97 using IntegrityCheckTransform::PopulatePartitionKey;
98 using IntegrityCheckTransform::AllBasicBlocksChecked;
99 using IntegrityCheckTransform::IsBogusBlock;
100 using IntegrityCheckTransform::PopulateCheckMaps;
101 using IntegrityCheckTransform::RandomlySelectChecker;
102 using IntegrityCheckTransform::AddReference;
103 using IntegrityCheckTransform::GetBasicBlockIdByLabel;
104 using IntegrityCheckTransform::TransformBasicBlockSubGraph;
105 using IntegrityCheckTransform::ProcessAllBlocks;
106 using IntegrityCheckTransform::GenerateBasicBlockCombinations;
107 using IntegrityCheckTransform::ShouldProcessBlock;
108 using IntegrityCheckTransform::TransformBlockGraph;
109
110 TestIntegrityCheckTransform()
111 : IntegrityCheckTransform(std::set<std::string>(),1.0f) {
112 }
113
114 void ResetTransform();
115
116 };
117
118
119
120
121 // Cleans state of the IntegrityCheckTransform
122 void TestIntegrityCheckTransform::ResetTransform() {
123 this->hash_block_ = NULL;
124 this->xhash_block_ = NULL;
125 this->response_block_ = NULL;
126 this->nr_hashes_patched_ = 0;
127 this->nr_pc_relative_refs_ = 0;
128 this->num_chunks_per_block = 0;
129 this->chunk_checking_coverage = 0;
130 this->label_name_to_block_.clear();
131 this->dll_id_to_block_reference_.clear();
132 this->adjust_label_by_offset_.clear();
133 this->target_names_.clear();
134 this->subgraph_vector_.clear();
135 this->checker_to_checkee_map_.clear();
136 this->is_bb_checked_map_.clear();
137 this->basic_block_has_ref_.clear();
138 this->basic_block_sizes_.clear();
139 this->precomputed_hashes_.clear();
140 this->partition_map_.clear();
141 this->partition_unit_map_.clear();
142 this->id_to_label_.clear();
143 this->ic_block_reference_free_chunks.clear();
144 this->ic_block_chunk_index_map_.clear();
145 this->ic_chunk_checker_to_checkee_map_.clear();
146 }
147
148 class IntegrityCheckTransformTest : public testing::TestDllTransformTest {
149 protected:
150 TestIntegrityCheckTransform tx_;
151 //static int *x;
152 static void SetUpTestCase(){
153 //x = new int[10];
154 }
155 static void TearDownTestCase(){
156 // delete x;
157 }
158 };
159
160 } // namespace
161
162 TEST_F(IntegrityCheckTransformTest, CheckIsIdInParitionUnitMap) {
163 ASSERT_FALSE(tx_.IsIdInPartitionUnitMap(0));
164 ASSERT_FALSE(tx_.IsIdInPartitionUnitMap(125));
165
166 std::set<uint64> st;
167 st.insert(125);
168 std::pair<int, std::set<uint64>> x(0, st);
169 tx_.partition_unit_map_.insert(x);
170
171 ASSERT_TRUE(tx_.IsIdInPartitionUnitMap(125));
172 ASSERT_FALSE(tx_.IsIdInPartitionUnitMap(123));
173
174 tx_.partition_unit_map_.erase(tx_.partition_unit_map_.find(0));
175 ASSERT_FALSE(tx_.IsIdInPartitionUnitMap(125));
176
177 tx_.ResetTransform();
178 }
179
180
181 TEST_F(IntegrityCheckTransformTest, CheckGenerateLabelToBlockMap) {
182 BlockGraph *bgraph = NULL;
183 BlockGraph::Block *test_block_a = NULL;
184 BlockGraph::Block *test_block_b = NULL;
185 BlockGraph::Block *test_block_c = NULL;
186
187 bgraph = new BlockGraph();
188 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "sample a");
189 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "sample b");
190 test_block_c = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "sample c");
191 test_block_a->SetLabel(10, BlockGraph::Label("test a", BlockGraph::CODE_LABEL) );
192 test_block_b->SetLabel(20, BlockGraph::Label("test b", BlockGraph::CODE_LABEL) );
193 test_block_c->SetLabel(500, BlockGraph::Label("test c", BlockGraph::CODE_LABEL ));
194
195 tx_.GenerateLabelToBlockMap(bgraph);
196 // Check for presence and value
197 auto res = tx_.label_name_to_block_.find("test a");
198 ASSERT_TRUE(res != tx_.label_name_to_block_.end());
199 ASSERT_TRUE(res->second.first == test_block_a);
200 res = tx_.label_name_to_block_.find("test b");
201 ASSERT_TRUE(res != tx_.label_name_to_block_.end());
202 ASSERT_TRUE(res->second.first == test_block_b);
203 res = tx_.label_name_to_block_.find("test c");
204 ASSERT_TRUE(res != tx_.label_name_to_block_.end());
205 ASSERT_TRUE(res->second.first == test_block_c);
206
207 res = tx_.label_name_to_block_.find("test d");
208 ASSERT_TRUE(res == tx_.label_name_to_block_.end());
209
210 tx_.ResetTransform();
211 delete bgraph;
212 }
213
214 TEST_F(IntegrityCheckTransformTest, CheckUpdateLabelToBlockMap) {
215 BlockGraph *bgraph = NULL;
216 BlockGraph::Block *test_block = NULL;
217
218 bgraph = new BlockGraph();
219 test_block = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "sample");
220 test_block->SetLabel(10, BlockGraph::Label("test a", BlockGraph::CODE_LABEL));
221 test_block->SetLabel(20, BlockGraph::Label("test b", BlockGraph::CODE_LABEL));
222 test_block->SetLabel(500, BlockGraph::Label("test c", BlockGraph::CODE_LABEL)) ;
223
224 tx_.UpdateLabelToBlockMap(test_block);
225
226 // Check for presence and value
227 auto res = tx_.label_name_to_block_.find("test a");
228 ASSERT_TRUE(res != tx_.label_name_to_block_.end());
229 ASSERT_TRUE(res->second.first == test_block);
230 res = tx_.label_name_to_block_.find("test b");
231 ASSERT_TRUE(res != tx_.label_name_to_block_.end());
232 ASSERT_TRUE(res->second.first == test_block);
233 res = tx_.label_name_to_block_.find("test c");
234 ASSERT_TRUE(res != tx_.label_name_to_block_.end());
235 ASSERT_TRUE(res->second.first == test_block);
236
237 res = tx_.label_name_to_block_.find("test d");
238 ASSERT_TRUE(res == tx_.label_name_to_block_.end());
239
240 tx_.ResetTransform();
241 delete bgraph;
242 }
243
244 TEST_F(IntegrityCheckTransformTest, CheckAllBasicBlocksChecked) {
245 std::set<uint64> test_set;
246 test_set.insert(0);
247
248 std::map<std::set<uint64>, int> check_order;
249 check_order.insert(std::pair<std::set<uint64>, int>(test_set, 0));
250
251 ASSERT_TRUE(tx_.is_bb_checked_map_[0] == 0);
252 ASSERT_TRUE(tx_.AllBasicBlocksChecked(check_order) == false);
253
254 tx_.is_bb_checked_map_.insert(std::pair<uint64, int > (0, 1));
255 ASSERT_FALSE(tx_.AllBasicBlocksChecked(check_order) == true);
256
257 tx_.ResetTransform();
258 }
259
260 TEST_F(IntegrityCheckTransformTest, CheckPopulateCheckMaps) {
261 // TODO: Understand how it works
262 }
263
264 TEST_F(IntegrityCheckTransformTest, CheckIsBogusBlock) {
265 BlockGraph *bgraph = new BlockGraph();
266 BlockGraph::Block *test_block = NULL;
267 test_block = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "sample a");
268
269 ASSERT_FALSE(tx_.IsBogusBlock(test_block));
270
271 std::set<uint64> test_set;
272 test_set.insert(test_block->id());
273 std::pair<int, std::set<uint64>> x(0, test_set);
274 tx_.partition_unit_map_.insert(x);
275
276 ASSERT_TRUE(tx_.IsBogusBlock(test_block));
277
278 tx_.ResetTransform();
279 delete bgraph;
280 }
281
282 TEST_F(IntegrityCheckTransformTest, CheckPatchBlockReference) {
283 BlockGraph *bgraph = NULL;
284 BlockGraph::Block *test_block_a = NULL;
285 BlockGraph::Block *test_block_b = NULL;
286 BlockGraph::Block *test_block_c = NULL;
287
288 bgraph = new BlockGraph();
289 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
290 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_b");
291 test_block_c = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "code_block");
292
293 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
294 subgraph->set_original_block(test_block_c);
295 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
296 0x60000000);
297
298 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
299 BlockGraph::CODE_BLOCK,
300 code_section->id(), 1, 0);
301
302 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
303 auto inst_iter = bb->instructions().begin();
304 block_graph::BasicBlockAssembler assm(inst_iter,
305 &bb->instructions());
306
307 int original_offset = 100;
308 int label_offset = 10;
309 assm.push(block_graph::Operand(block_graph::Displacement(test_block_a,
310 original_offset)));
311
312 // Insert the label and update label_name_to_block_
313 test_block_b->SetLabel(label_offset,
314 BlockGraph::Label("Test Label",
315 BlockGraph::CODE_LABEL));
316 auto lab_it(test_block_b->labels().begin());
317 tx_.label_name_to_block_[lab_it->second.name()] =
318 std::make_pair(test_block_b, lab_it->first);
319
320 // Prepare parameters for calling PatchBlockReference
321 auto label_to_block_it = tx_.label_name_to_block_.find(lab_it->second.name());
322 CHECK(label_to_block_it != tx_.label_name_to_block_.end());
323 auto reference_free_block = label_to_block_it->second.first;
324 uint32 new_bb_ref_offset = label_to_block_it->second.second;
325 int intermediate_offset = 150;
326
327 // Check initial offset and reference
328 inst_iter = bb->instructions().begin();
329 Instruction::BasicBlockReferenceMap &ref_block_map =
330 inst_iter->references();
331 auto instruction_references_it = ref_block_map.begin();
332 BlockGraph::Offset reference_offset =
333 instruction_references_it->first;
334 block_graph::BasicBlockReference old_bb_ref =
335 instruction_references_it->second;
336 ASSERT_TRUE(old_bb_ref.block() == test_block_a);
337 ASSERT_TRUE(old_bb_ref.offset() == original_offset);
338
339 // Patch the instruction without changing the block
340 tx_.PatchBlockReference(inst_iter, reference_free_block,
341 intermediate_offset, false);
342
343 // Check the modifications
344 instruction_references_it = inst_iter->references().begin();
345 reference_offset = instruction_references_it->first;
346 block_graph::BasicBlockReference new_bb_ref =
347 instruction_references_it->second;
348
349 ASSERT_TRUE(new_bb_ref.block() == test_block_a);
350 ASSERT_TRUE(new_bb_ref.offset() == intermediate_offset);
351
352 // Patch the instruction including changing the block
353 tx_.PatchBlockReference(inst_iter, reference_free_block,
354 new_bb_ref_offset, true);
355
356 instruction_references_it = inst_iter->references().begin();
357 reference_offset = instruction_references_it->first;
358 new_bb_ref = instruction_references_it->second;
359
360 ASSERT_TRUE(new_bb_ref.block() == test_block_b);
361 ASSERT_TRUE((uint32)new_bb_ref.offset() == new_bb_ref_offset);
362
363 tx_.ResetTransform();
364 delete bgraph;
365 delete subgraph;
366 }
367
368 TEST_F(IntegrityCheckTransformTest, CheckCheckHash) {
369 BlockGraph *bgraph = new BlockGraph();
370 BlockGraph::Block *test_block_b = NULL;
371 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 2000, "sample b");
372 base::StringPiece test_block_tag = "1";
373 auto test_block_label = block_graph::BlockGraph::Label(
374 test_block_tag,
375 BlockGraph::CODE_LABEL);
376 uint64 test_block_id = 1;
377 uint32 test_block_size = 1;
378 // push eax equals to 0x50
379 uint8 test_block_value = 0x50;
380 //prepare id to label map
381 tx_.id_to_label_[test_block_id] = test_block_label;
382 //set the size
383 tx_.basic_block_sizes_[test_block_id] = test_block_size;
384
385 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
386 subgraph->set_original_block(test_block_b);
387 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
388 0x60000000);
389
390 subgraph->AddBlockDescription("sample c", code_section->name(),
391 BlockGraph::CODE_BLOCK,
392 code_section->id(), 1, 0);
393
394 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("sample b");
395
396 auto inst_iter = bb->instructions().begin();
397 block_graph::BasicBlockAssembler assm(inst_iter,
398 &bb->instructions());
399
400 assm.push(assm::eax);
401 //add label to the block
402 auto instr = bb->instructions().begin();
403 instr->set_label(test_block_label);
404
405
406 std::vector<uint8> test_buffer;
407 test_buffer.insert(test_buffer.begin(), test_block_value);
408 //offset in the test buffer
409 bb->set_offset(0);
410 tx_.CheckHash(bb, test_buffer);
411
412 //we should have a hash computed for this block
413 ASSERT_TRUE(tx_.precomputed_hashes_[test_block_id] == test_block_value);
414
415 tx_.ResetTransform();
416 delete bgraph;
417 delete subgraph;
418 }
419
420 TEST_F(IntegrityCheckTransformTest, CheckFixPrecomputedHashes) {
421 //what the hell to test here!
422 }
423
424 TEST_F(IntegrityCheckTransformTest, CheckRecomputeXorChunks){
425 uint64 test_block_id = 1;
426 uint8 test_old_size[1] = { 1 };
427 uint8 test_new_size[1] = { 2 };
428 uint64 test_chunk_bb_id = 1;
429 uint32 test_chunk_index = 0;
430 uint32 test_chunk_size = 1;
431 uint8 test_chunk_hash = 0x50;
432 //new hash = old hash ^ old_size ^ new_size
433 uint8 test_chunk_new_hash = 0x53;
434
435 uint64 test_vector_index = 0;
436 tx_.ic_block_chunk_index_map_[tx_.GetChunkUniqueKey(test_chunk_bb_id,
437 test_chunk_index)] =
438 test_vector_index;
439
440 ChunkInfo test_chunk(test_chunk_bb_id,test_chunk_size,
441 test_chunk_hash, test_chunk_index,0);
442 tx_.ic_block_reference_free_chunks.insert(
443 tx_.ic_block_reference_free_chunks.begin(), test_chunk);
444
445 tx_.RecomputeXorChunks(test_block_id, test_old_size, test_new_size,
446 test_chunk_bb_id, test_chunk_index);
447
448 //we should have a hash computed for this block
449 auto updated_chunk = tx_.ic_block_reference_free_chunks[test_vector_index];
450
451 ASSERT_EQ(updated_chunk.hash_,test_chunk_new_hash);
452
453 tx_.ResetTransform();
454 }
455 TEST_F(IntegrityCheckTransformTest, CheckGetHashBlock) {
456 ASSERT_TRUE(tx_.GetHashBlock()==NULL);
457 }
458 TEST_F(IntegrityCheckTransformTest, CheckSetHashBlock) {
459 BlockGraph *bgraph = NULL;
460 BlockGraph::Block *test_block_a = NULL;
461
462 bgraph = new BlockGraph();
463 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
464
465 tx_.SetHashBlock(test_block_a);
466 auto ret_block = tx_.GetHashBlock();
467 ASSERT_TRUE(ret_block == test_block_a);
468 tx_.ResetTransform();
469 delete bgraph;
470 }
471
472
473 TEST_F(IntegrityCheckTransformTest, CheckRecomputePivot){
474 BlockGraph *bgraph = new BlockGraph();
475 BlockGraph::Block *test_block_b = NULL;
476 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 2000, "sample b");
477 uint8 old_hash = 0x1;
478 // push eax, pivot, sub al, old hash
479 uint8 test_block_data[5] = { 0x50, 0x0, 0x2c, old_hash };
480
481 test_block_b->SetData(test_block_data, sizeof(test_block_data));
482
483
484 uint64 test_block_id = 1;
485 uint8 test_precomputed_hash = 0x7c;
486 uint8 test_precomputed_xor = 1;
487 uint32 test_pivot_offset = 1;
488 uint32 test_sub_offset = 2;
489 tx_.RecomputePivot(test_block_id, test_precomputed_hash, test_precomputed_xor,
490 test_pivot_offset, test_sub_offset, test_block_b);
491 // pivot + new hash = old hash
492 uint8 hash_diff = test_block_b->data()[test_pivot_offset] +
493 test_block_b->data()[test_sub_offset + 1];
494 bool is_pivot_correct = hash_diff == old_hash;
495
496 ASSERT_TRUE(is_pivot_correct);
497 delete bgraph;
498
499 }
500
501 TEST_F(IntegrityCheckTransformTest, CheckComputeAggregatedBlocksHash){
502 uint64 test_bb_id = 1;
503 std::map<uint64, int> test_checkee_map;
504 test_checkee_map[2] = 1;
505 test_checkee_map[3] = -1;
506 tx_.checker_to_checkee_map_[test_bb_id] = test_checkee_map;
507 tx_.precomputed_hashes_[2] = 0x20;
508 tx_.precomputed_hashes_[3] = 0x10;
509 uint8 computed_hash = tx_.ComputeAggregatedBlocksHash(test_bb_id);
510 ASSERT_EQ(0x10, computed_hash);
511
512 tx_.ResetTransform();
513 }
514 TEST_F(IntegrityCheckTransformTest, CheckComputeAggregatedChunksHash){
515 uint8 hash1 = 0x1;
516 uint8 hash2 = 0x2;
517 tx_.ic_block_reference_free_chunks.insert(
518 tx_.ic_block_reference_free_chunks.begin(), ChunkInfo(1, 1, hash1, 0, 0));
519 tx_.ic_block_reference_free_chunks.insert(
520 tx_.ic_block_reference_free_chunks.begin(), ChunkInfo(1, 1, hash2, 0, 0));
521 std::set<uint32> test_chunk_index_set;
522 test_chunk_index_set.insert(0);
523 test_chunk_index_set.insert(1);
524 uint8 computed_hash = tx_.ComputeAggregatedChunksHash(test_chunk_index_set);
525 ASSERT_EQ(0x3, computed_hash);
526
527 tx_.ResetTransform();
528 }
529
530 TEST_F(IntegrityCheckTransformTest, CheckPatchPivot){
531 BlockGraph *bgraph = new BlockGraph();
532 BlockGraph::Block *test_block_b = NULL;
533 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 2000, "sample b");
534 base::StringPiece test_block_tag = "1";
535 auto test_block_label = block_graph::BlockGraph::Label(
536 test_block_tag,
537 BlockGraph::CODE_LABEL);
538 uint64 test_block_id = 1;
539 uint32 test_block_size = 1;
540 //prepare id to label map
541 tx_.id_to_label_[test_block_id] = test_block_label;
542 //set the size
543 tx_.basic_block_sizes_[test_block_id] = test_block_size;
544
545 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
546 subgraph->set_original_block(test_block_b);
547 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
548 0x60000000);
549
550 subgraph->AddBlockDescription("sample c", code_section->name(),
551 BlockGraph::CODE_BLOCK,
552 code_section->id(), 1, 0);
553
554 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("sample b");
555
556 auto inst_iter = bb->instructions().begin();
557 block_graph::BasicBlockAssembler assm(inst_iter,
558 &bb->instructions());
559
560 uint8 old_hash = 0x1;
561
562 assm.push(assm::eax);
563 assm.data(0);
564 assm.sub(assm::al,block_graph::Immediate(old_hash,
565 assm::ValueSize::kSize8Bit));
566 //add labels to the block
567 auto instr = bb->instructions().begin();
568 instr->set_label(test_block_label);
569 uint32 test_pivot_offset = 1;
570 uint32 test_sub_offset = 2;
571 uint32 test_hash_offset = 3;
572 tx_.label_name_to_block_["Pivot:1"] = std::make_pair(test_block_b,
573 test_pivot_offset);
574 tx_.label_name_to_block_["sub 1"] = std::make_pair(test_block_b,
575 test_sub_offset);
576
577 uint64 test_bb_id = 1;
578 std::map<uint64, int> test_checkee_map;
579 test_checkee_map[2] = 1;
580 test_checkee_map[3] = -1;
581 tx_.checker_to_checkee_map_[test_bb_id] = test_checkee_map;
582 tx_.precomputed_hashes_[2] = 0x20;
583 tx_.precomputed_hashes_[3] = 0x10;
584
585
586 uint8 hash1 = 0x1;
587 uint8 hash2 = 0x2;
588 tx_.ic_block_reference_free_chunks.insert(
589 tx_.ic_block_reference_free_chunks.begin(), ChunkInfo(1, 1, hash1, 0, 0));
590 tx_.ic_block_reference_free_chunks.insert(
591 tx_.ic_block_reference_free_chunks.begin(), ChunkInfo(1, 1, hash2, 0, 0));
592 std::set<uint32> test_chunk_index_set;
593 test_chunk_index_set.insert(0);
594 test_chunk_index_set.insert(1);
595 tx_.ic_chunk_checker_to_checkee_map_[test_bb_id] = test_chunk_index_set;
596
597
598 // push eax, pivot, sub al, old hash
599 uint8 test_block_data[5] = { 0x50, 0x0, 0x2c, old_hash };
600
601 test_block_b->SetData(test_block_data, sizeof(test_block_data));
602
603
604 FILE *file=NULL;
605 tx_.PatchPivot(bb, subgraph, bgraph, file);
606
607 //hash = precomputed sum + precomputed xor
608 //hash = 0x10 + 0x3
609 ASSERT_EQ(test_block_b->data()[test_hash_offset], 0x13);
610
611 uint8 hash_diff = test_block_b->data()[test_pivot_offset] +
612 test_block_b->data()[test_hash_offset];
613 bool is_pivot_correct = hash_diff == old_hash;
614
615 ASSERT_TRUE(is_pivot_correct);
616
617 tx_.ResetTransform();
618
619 delete bgraph;
620 delete subgraph;
621 }
622
623 TEST_F(IntegrityCheckTransformTest, CheckPatchSizesByLabel){
624 BlockGraph *bgraph = new BlockGraph();
625 BlockGraph::Block *test_block_b = NULL;
626 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 2000, "sample b");
627 base::StringPiece test_block_tag = "1";
628 auto test_block_label = block_graph::BlockGraph::Label(
629 test_block_tag,
630 BlockGraph::CODE_LABEL);
631 uint64 test_block_id = 1;
632 uint32 test_block_size = 1;
633 //prepare id to label map
634 tx_.id_to_label_[test_block_id] = test_block_label;
635 //set the size
636 tx_.basic_block_sizes_[test_block_id] = test_block_size;
637
638 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
639 subgraph->set_original_block(test_block_b);
640 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
641 0x60000000);
642
643 subgraph->AddBlockDescription("sample c", code_section->name(),
644 BlockGraph::CODE_BLOCK,
645 code_section->id(), 1, 0);
646
647 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("sample b");
648
649 auto inst_iter = bb->instructions().begin();
650 block_graph::BasicBlockAssembler assm(inst_iter,
651 &bb->instructions());
652
653 uint32 test_old_block_size = 0x10;
654 uint32 test_new_block_size = 0x11;
655 uint64 test_reference_block_id = 2;
656 assm.push(assm::eax);
657 assm.push(block_graph::Immediate(test_old_block_size, assm::kSize32Bit));
658
659
660 inst_iter = bb->instructions().begin();
661 //set chunk finger label
662 inst_iter->set_label(block_graph::BlockGraph::Label("n 1 0",
663 BlockGraph::CODE_LABEL));
664 ++inst_iter;
665 inst_iter->set_label(block_graph::BlockGraph::Label("size 2 1",
666 BlockGraph::CODE_LABEL));
667 tx_.basic_block_sizes_[test_reference_block_id] = test_new_block_size;
668
669 uint64 test_chunk_bb_id = 1;
670 uint32 test_chunk_index = 0;
671 uint32 test_chunk_size = 1;
672 uint8 test_chunk_hash = 0x50;
673
674
675 uint64 test_vector_index = 0;
676 tx_.ic_block_chunk_index_map_[tx_.GetChunkUniqueKey(test_chunk_bb_id,
677 test_chunk_index)] =
678 test_vector_index;
679
680 ChunkInfo test_chunk(test_chunk_bb_id, test_chunk_size,
681 test_chunk_hash, test_chunk_index, 0);
682 tx_.ic_block_reference_free_chunks.insert(
683 tx_.ic_block_reference_free_chunks.begin(), test_chunk);
684
685 tx_.PatchBlockReferencesAndSizes(bb, subgraph, bgraph);
686 ASSERT_EQ(inst_iter->data()[1], test_new_block_size);
687
688 tx_.ResetTransform();
689 delete bgraph;
690 delete subgraph;
691
692 }
693
694 TEST_F(IntegrityCheckTransformTest, CheckPatchBlockReferenceByLabel) {
695 BlockGraph *bgraph = NULL;
696 BlockGraph::Block *test_block_a = NULL;
697
698 bgraph = new BlockGraph();
699 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
700
701 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
702 subgraph->set_original_block(test_block_a);
703 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
704 0x60000000);
705
706 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
707 BlockGraph::CODE_BLOCK,
708 code_section->id(), 1, 0);
709
710 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
711 auto inst_iter = bb->instructions().begin();
712 block_graph::BasicBlockAssembler assm(inst_iter,
713 &bb->instructions());
714
715 int original_offset = 100;
716 assm.push(block_graph::Immediate(test_block_a, original_offset));
717 inst_iter = bb->instructions().begin();
718 inst_iter->set_label(BlockGraph::Label("block 2",
719 BlockGraph::CODE_LABEL));
720 int intermediate_offset = 150;
721
722 //move block offset
723 tx_.label_name_to_block_["2"] =
724 std::make_pair(test_block_a, intermediate_offset);
725
726 // Check initial offset and reference
727 inst_iter = bb->instructions().begin();
728 Instruction::BasicBlockReferenceMap &ref_block_map =
729 inst_iter->references();
730 auto instruction_references_it = ref_block_map.begin();
731 BlockGraph::Offset reference_offset = instruction_references_it->first;
732 block_graph::BasicBlockReference old_bb_ref =
733 instruction_references_it->second;
734 ASSERT_TRUE(old_bb_ref.block() == test_block_a);
735 ASSERT_TRUE(old_bb_ref.offset() == original_offset);
736
737
738
739 tx_.PatchBlockReferencesAndSizes(bb, subgraph, bgraph);
740
741 inst_iter = bb->instructions().begin();
742 // Check the modifications
743 instruction_references_it = inst_iter->references().begin();
744 reference_offset = instruction_references_it->first;
745 block_graph::BasicBlockReference new_bb_ref =
746 instruction_references_it->second;
747
748 ASSERT_TRUE(new_bb_ref.block() == test_block_a);
749 ASSERT_TRUE(new_bb_ref.offset() == intermediate_offset);
750 }
751
752 TEST_F(IntegrityCheckTransformTest, CheckPatchChunkReferenceByLabel) {
753 BlockGraph *bgraph = NULL;
754 BlockGraph::Block *test_block_a = NULL;
755
756 bgraph = new BlockGraph();
757 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
758
759 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
760 subgraph->set_original_block(test_block_a);
761 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
762 0x60000000);
763
764 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
765 BlockGraph::CODE_BLOCK,
766 code_section->id(), 1, 0);
767
768 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
769 auto inst_iter = bb->instructions().begin();
770 block_graph::BasicBlockAssembler assm(inst_iter,
771 &bb->instructions());
772
773 int original_offset = 100;
774 assm.push(block_graph::Immediate(test_block_a, original_offset));
775 inst_iter = bb->instructions().begin();
776 inst_iter->set_label(BlockGraph::Label("nrc 2 0",
777 BlockGraph::CODE_LABEL));
778 int intermediate_offset = 150;
779
780 //move block offset
781 tx_.label_name_to_block_["n 2 0"] =
782 std::make_pair(test_block_a, intermediate_offset);
783
784 // Check initial offset and reference
785 inst_iter = bb->instructions().begin();
786 Instruction::BasicBlockReferenceMap &ref_block_map =
787 inst_iter->references();
788 auto instruction_references_it = ref_block_map.begin();
789 BlockGraph::Offset reference_offset = instruction_references_it->first;
790 block_graph::BasicBlockReference old_bb_ref =
791 instruction_references_it->second;
792 ASSERT_TRUE(old_bb_ref.block() == test_block_a);
793 ASSERT_TRUE(old_bb_ref.offset() == original_offset);
794
795
796
797 tx_.PatchBlockReferencesAndSizes(bb, subgraph, bgraph);
798
799 inst_iter = bb->instructions().begin();
800 // Check the modifications
801 instruction_references_it = inst_iter->references().begin();
802 reference_offset = instruction_references_it->first;
803 block_graph::BasicBlockReference new_bb_ref =
804 instruction_references_it->second;
805
806 ASSERT_TRUE(new_bb_ref.block() == test_block_a);
807 ASSERT_TRUE(new_bb_ref.offset() == intermediate_offset);
808 }
809 TEST_F(IntegrityCheckTransformTest, CheckAddChunkIntegrityCheckCode) {
810
811 uint64 test_bb_id = 1;
812 //set total chunks
813 tx_.num_chunks_per_block = 10;
814
815 BlockGraph *bgraph = NULL;
816 BlockGraph::Block *test_block_a = NULL;
817
818 bgraph = new BlockGraph();
819 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
820
821 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
822 subgraph->set_original_block(test_block_a);
823 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
824 0x60000000);
825
826 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
827 BlockGraph::CODE_BLOCK,
828 code_section->id(), 1, 0);
829
830 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
831 auto inst_iter = bb->instructions().begin();
832 block_graph::BasicBlockAssembler assm(inst_iter,
833 &bb->instructions());
834
835 assm.push(assm::eax);
836 inst_iter = bb->instructions().begin();
837 //set block id label
838 auto test_block_label = BlockGraph::Label(std::to_string(test_bb_id),
839 BlockGraph::CODE_LABEL);
840 inst_iter->set_label(test_block_label);
841 //set a dummy hash block
842 tx_.xhash_block_ = test_block_a;
843
844 //prepare id to label map
845 tx_.id_to_label_[test_bb_id] = test_block_label;
846 //set block size
847 uint32 old_size = inst_iter->size();
848 tx_.basic_block_sizes_[test_bb_id] = old_size;
849
850 //set checker checkee map
851
852 std::map<uint64, int> test_checkee_map;
853 test_checkee_map[2] = 1;
854 test_checkee_map[3] = -1;
855 tx_.checker_to_checkee_map_[test_bb_id] = test_checkee_map;
856 tx_.precomputed_hashes_[2] = 0x20;
857 tx_.precomputed_hashes_[3] = 0x10;
858
859 //set chunk checker map
860 uint8 hash1 = 0x1;
861 std::set<uint32> test_chunk_index_set;
862 for (uint32 i = 0; i < tx_.num_chunks_per_block; ++i){
863 tx_.ic_block_reference_free_chunks.insert(
864 tx_.ic_block_reference_free_chunks.begin(), ChunkInfo(1, 1, hash1, i,0)) ;
865 test_chunk_index_set.insert(i);
866 char *buffersearch = new char[50];
867 sprintf_s(buffersearch, 50, "n %llu %lu", test_bb_id, i);
868 tx_.label_name_to_block_[buffersearch] = std::make_pair(test_block_a, 0);
869 delete[] buffersearch;
870 }
871 tx_.ic_chunk_checker_to_checkee_map_[test_bb_id] = test_chunk_index_set;
872
873
874 tx_.AddChunkIntegrityCheckCode(bb, subgraph, bgraph);
875
876 //Ensure basic_block_sizes_[bb_id] is larger than before
877 ASSERT_GT(tx_.basic_block_sizes_[test_bb_id], old_size);
878 //Check there are equal number of chunks and nrc labels
879 inst_iter = bb->instructions().begin();
880 uint32 nr_added_labels = 0;
881 std::string chunk_pointerlabel = "nrc";
882 for (; inst_iter != bb->instructions().end(); ++inst_iter){
883 if (inst_iter->label().name()
884 .compare(0, chunk_pointerlabel.length(), chunk_pointerlabel) == 0){
885 ++nr_added_labels;
886 }
887 }
888
889 //Ensure kNumChunksPerBlock == #chunks
890 ASSERT_EQ(tx_.num_chunks_per_block, nr_added_labels);
891
892 tx_.ResetTransform();
893 delete bgraph;
894 delete subgraph;
895 }
896
897 TEST_F(IntegrityCheckTransformTest, CheckAddIntegrityCheckCode) {
898 //check labels block, pivot, size, sub instruction
899 uint64 test_bb_id = 1;
900 uint64 test_checkee1_id = 2;
901 uint64 test_checkee2_id = 3;
902 BlockGraph *bgraph = NULL;
903 BlockGraph::Block *test_block_a = NULL;
904 BlockGraph::Block *test_block_b = NULL;
905
906 bgraph = new BlockGraph();
907 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
908 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_b");
909
910 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
911 subgraph->set_original_block(test_block_a);
912 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
913 0x60000000);
914
915 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
916 BlockGraph::CODE_BLOCK,
917 code_section->id(), 1, 0);
918
919 BasicBlockSubGraph* subgraph_b = new BasicBlockSubGraph();
920 subgraph_b->set_original_block(test_block_b);
921
922 subgraph_b->AddBlockDescription("test_subgraph", code_section->name(),
923 BlockGraph::CODE_BLOCK,
924 code_section->id(), 1, 0);
925
926
927 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
928 auto inst_iter = bb->instructions().begin();
929 block_graph::BasicBlockAssembler assm(inst_iter,
930 &bb->instructions());
931
932 assm.push(assm::eax);
933 inst_iter = bb->instructions().begin();
934 //set block id label
935 auto test_block_label = BlockGraph::Label(std::to_string(test_bb_id),
936 BlockGraph::CODE_LABEL);
937 inst_iter->set_label(test_block_label);
938 //prepare id to label map
939 tx_.id_to_label_[test_bb_id] = test_block_label;
940 //set block id label
941 auto test_checkee1_label = BlockGraph::Label(std::to_string(test_checkee1_id),
942 BlockGraph::CODE_LABEL);
943 tx_.id_to_label_[test_checkee1_id] = test_checkee1_label;
944 tx_.label_name_to_block_[std::to_string(test_checkee1_id)] =
945 std::make_pair(test_block_b, 0);
946 auto test_checkee2_label = BlockGraph::Label(std::to_string(test_checkee2_id),
947 BlockGraph::CODE_LABEL);
948 tx_.id_to_label_[test_checkee2_id] = test_checkee2_label;
949
950 tx_.label_name_to_block_[std::to_string(test_checkee2_id)] =
951 std::make_pair(test_block_b, 0);
952 //set a dummy hash block
953 tx_.hash_block_ = test_block_a;
954 //set dummy response block
955 tx_.response_block_ = test_block_a;
956 //set block size
957 uint32 old_size = inst_iter->size();
958 tx_.basic_block_sizes_[test_bb_id] = old_size;
959 tx_.basic_block_sizes_[test_checkee1_id] = 1;
960 tx_.basic_block_sizes_[test_checkee2_id] = 1;
961 //set checker checkee map
962
963 std::map<uint64, int> test_checkee_map;
964 test_checkee_map[test_checkee1_id] = 1;
965 test_checkee_map[test_checkee2_id] = -1;
966 tx_.checker_to_checkee_map_[test_bb_id] = test_checkee_map;
967 tx_.precomputed_hashes_[test_checkee1_id] = 0x20;
968 tx_.precomputed_hashes_[test_checkee2_id] = 0x10;
969
970 tx_.AddIntegrityCheckCode(bb, subgraph, bgraph);
971
972 //Ensure basic_block_sizes_[bb_id] is larger than before
973 ASSERT_GT(tx_.basic_block_sizes_[test_bb_id], old_size);
974 //Check there are equal number of chunks and nrc labels
975 inst_iter = bb->instructions().begin();
976 uint32 nr_added_block_labels = 0;
977 std::string block_pointerlabel = "block";
978 uint32 nr_added_size_labels = 0;
979 std::string size_pointerlabel = "size";
980 uint32 nr_added_pivot_labels = 0;
981 std::string pivot_pointerlabel = "Pivot";
982 uint32 nr_added_sub_labels = 0;
983 std::string sub_pointerlabel = "sub";
984 for (; inst_iter != bb->instructions().end(); ++inst_iter){
985 if (inst_iter->label().name()
986 .compare(0, block_pointerlabel.length(), block_pointerlabel) == 0){
987 ++nr_added_block_labels;
988 } else if (inst_iter->label().name()
989 .compare(0, size_pointerlabel.length(), size_pointerlabel) == 0){
990 ++nr_added_size_labels;
991 }
992 else if (inst_iter->label().name().compare(0, pivot_pointerlabel.length(),
993 pivot_pointerlabel) == 0){
994 ++nr_added_pivot_labels;
995 } else if (inst_iter->label().name().compare(0, sub_pointerlabel.length(),
996 sub_pointerlabel) == 0){
997 ++nr_added_sub_labels;
998 }
999
1000 }
1001
1002 //Ensure kNumChunksPerBlock == #chunks
1003 ASSERT_EQ(test_checkee_map.size(), nr_added_block_labels);
1004 ASSERT_EQ(test_checkee_map.size(), nr_added_size_labels);
1005 ASSERT_EQ(1, nr_added_pivot_labels);
1006 ASSERT_EQ(1, nr_added_sub_labels);
1007
1008 tx_.ResetTransform();
1009 delete bgraph;
1010 delete subgraph;
1011 delete subgraph_b;
1012 }
1013
1014 TEST_F(IntegrityCheckTransformTest, CheckComputeChunksWhenInstructionHasLabel) {
1015 uint64 test_bb_id = 1;
1016 BlockGraph *bgraph = NULL;
1017 BlockGraph::Block *test_block_a = NULL;
1018
1019 bgraph = new BlockGraph();
1020 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
1021
1022 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
1023 subgraph->set_original_block(test_block_a);
1024 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
1025 0x60000000);
1026
1027 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
1028 BlockGraph::CODE_BLOCK,
1029 code_section->id(), 1, 0);
1030
1031 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
1032 auto inst_iter = bb->instructions().begin();
1033 block_graph::BasicBlockAssembler assm(inst_iter,
1034 &bb->instructions());
1035
1036 assm.push(assm::eax);
1037 assm.data(0);
1038
1039 auto test_label = BlockGraph::Label(std::to_string(test_bb_id),
1040 BlockGraph::CODE_LABEL);
1041 inst_iter = bb->instructions().begin();
1042 inst_iter->set_label(test_label);
1043 //Every checker comes with a pivot
1044 ++inst_iter;
1045 inst_iter->set_label(BlockGraph::Label("Pivot:",
1046 BlockGraph::CODE_LABEL));
1047
1048 tx_.id_to_label_[test_bb_id] = test_label;
1049
1050 //make the block a checker
1051
1052 uint64 test_checkee1_id = 2;
1053 uint64 test_checkee2_id = 3;
1054 std::map<uint64, int> test_checkee_map;
1055 test_checkee_map[test_checkee1_id] = 1;
1056 test_checkee_map[test_checkee2_id] = -1;
1057 tx_.checker_to_checkee_map_[test_bb_id] = test_checkee_map;
1058 tx_.precomputed_hashes_[test_checkee1_id] = 0x20;
1059 tx_.precomputed_hashes_[test_checkee2_id] = 0x10;
1060
1061
1062 tx_.ComputeChunks(bb);
1063
1064 //on instructions with label don't set chunk label
1065 ASSERT_EQ(0, tx_.ic_block_reference_free_chunks.size());
1066
1067 tx_.ResetTransform();
1068 delete bgraph;
1069 delete subgraph;
1070 }
1071 TEST_F(IntegrityCheckTransformTest, CheckComputeChunksWhenLastInstruction) {
1072 uint64 test_bb_id = 1;
1073 BlockGraph *bgraph = NULL;
1074 BlockGraph::Block *test_block_a = NULL;
1075
1076 bgraph = new BlockGraph();
1077 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
1078
1079 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
1080 subgraph->set_original_block(test_block_a);
1081 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
1082 0x60000000);
1083
1084 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
1085 BlockGraph::CODE_BLOCK,
1086 code_section->id(), 1, 0);
1087
1088 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
1089 auto inst_iter = bb->instructions().begin();
1090 block_graph::BasicBlockAssembler assm(inst_iter,
1091 &bb->instructions());
1092
1093 assm.push(assm::eax);
1094 assm.data(0);
1095 assm.push(assm::ebx);
1096
1097 auto test_label = BlockGraph::Label(std::to_string(test_bb_id),
1098 BlockGraph::CODE_LABEL);
1099 inst_iter = bb->instructions().begin();
1100 inst_iter->set_label(test_label);
1101 //Every checker comes with a pivot
1102 ++inst_iter;
1103 inst_iter->set_label(BlockGraph::Label("Pivot:",
1104 BlockGraph::CODE_LABEL));
1105
1106 tx_.id_to_label_[test_bb_id] = test_label;
1107
1108 //make the block a checker
1109
1110 uint64 test_checkee1_id = 2;
1111 uint64 test_checkee2_id = 3;
1112 std::map<uint64, int> test_checkee_map;
1113 test_checkee_map[test_checkee1_id] = 1;
1114 test_checkee_map[test_checkee2_id] = -1;
1115 tx_.checker_to_checkee_map_[test_bb_id] = test_checkee_map;
1116 tx_.precomputed_hashes_[test_checkee1_id] = 0x20;
1117 tx_.precomputed_hashes_[test_checkee2_id] = 0x10;
1118
1119
1120 tx_.ComputeChunks(bb);
1121
1122 //last push ebx should be recognized as a chunk
1123 ASSERT_EQ(1, tx_.ic_block_reference_free_chunks.size());
1124
1125 tx_.ResetTransform();
1126 delete bgraph;
1127 delete subgraph;
1128 }
1129
1130 TEST_F(IntegrityCheckTransformTest, CheckComputeChunksWhenAbsReferenceBetween) {
1131 uint64 test_bb_id = 1;
1132 BlockGraph *bgraph = NULL;
1133 BlockGraph::Block *test_block_a = NULL;
1134
1135 bgraph = new BlockGraph();
1136 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
1137
1138 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
1139 subgraph->set_original_block(test_block_a);
1140 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
1141 0x60000000);
1142
1143 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
1144 BlockGraph::CODE_BLOCK,
1145 code_section->id(), 1, 0);
1146
1147 BasicCodeBlock* bb = subgraph->AddBasicCodeBlock("basic_code_block");
1148 auto inst_iter = bb->instructions().begin();
1149 block_graph::BasicBlockAssembler assm(inst_iter,
1150 &bb->instructions());
1151
1152 assm.push(assm::eax);
1153 assm.data(0);
1154 assm.push(assm::ebx);
1155 assm.push(block_graph::Immediate(test_block_a, 0));
1156 assm.add(assm::eax, assm::ebx);
1157
1158 auto test_label = BlockGraph::Label(std::to_string(test_bb_id),
1159 BlockGraph::CODE_LABEL);
1160 inst_iter = bb->instructions().begin();
1161 inst_iter->set_label(test_label);
1162 //Every checker comes with a pivot
1163 ++inst_iter;
1164 inst_iter->set_label(BlockGraph::Label("Pivot:",
1165 BlockGraph::CODE_LABEL));
1166
1167 tx_.id_to_label_[test_bb_id] = test_label;
1168
1169 //make the block a checker
1170
1171 uint64 test_checkee1_id = 2;
1172 uint64 test_checkee2_id = 3;
1173 std::map<uint64, int> test_checkee_map;
1174 test_checkee_map[test_checkee1_id] = 1;
1175 test_checkee_map[test_checkee2_id] = -1;
1176 tx_.checker_to_checkee_map_[test_bb_id] = test_checkee_map;
1177 tx_.precomputed_hashes_[test_checkee1_id] = 0x20;
1178 tx_.precomputed_hashes_[test_checkee2_id] = 0x10;
1179
1180
1181 tx_.ComputeChunks(bb);
1182
1183 //push ebx and add eax,ebx are two chunks spearated by an abs reference
1184 ASSERT_EQ(2, tx_.ic_block_reference_free_chunks.size());
1185
1186 //push ebx is one byte
1187 ASSERT_EQ(1, tx_.ic_block_reference_free_chunks[0].size_);
1188 //add eax,ebx is two bytes
1189 ASSERT_EQ(2, tx_.ic_block_reference_free_chunks[1].size_);
1190
1191 tx_.ResetTransform();
1192 delete bgraph;
1193 delete subgraph;
1194 }
1195
1196 TEST_F(IntegrityCheckTransformTest, CheckAddChunkIntoIndexMap) {
1197 uint64 test_chunk_bb_id = 1;
1198 uint32 test_chunk_index = 0;
1199 uint32 test_vector_index = 0;
1200 tx_.AddChunkIntoIndexMap(test_chunk_bb_id,
1201 test_chunk_index,
1202 test_vector_index);
1203 ASSERT_EQ(test_vector_index, tx_.ic_block_chunk_index_map_[
1204 tx_.GetChunkUniqueKey(test_chunk_bb_id, test_chunk_index)]);
1205
1206 tx_.ResetTransform();
1207 }
1208
1209 TEST_F(IntegrityCheckTransformTest, CheckGetChunkUniqueKey) {
1210 uint64 test_chunk_bb_id = 1;
1211 uint32 test_chunk_index = 0;
1212 uint64 unique_id = tx_.GetChunkUniqueKey(test_chunk_bb_id, test_chunk_index);
1213
1214 ASSERT_NE(static_cast<uint64>(0), unique_id);
1215 tx_.ResetTransform();
1216 }
1217
1218 TEST_F(IntegrityCheckTransformTest, CheckGenerateChunkCombinations) {
1219 //build 2 checkers in two subgraphs because chunks are assigned to different
1220 //subgraphs
1221 BlockGraph *bgraph = NULL;
1222 BlockGraph::Block *test_block_a = NULL;
1223 BlockGraph::Block *test_block_b = NULL;
1224 uint64 test_bb1_id = 1;
1225 uint64 test_bb2_id = 4;
1226 std::vector<ChunkInfo> test_chunks;
1227
1228 bgraph = new BlockGraph();
1229 test_block_a = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_a");
1230 test_block_b = bgraph->AddBlock(BlockGraph::CODE_BLOCK, 1000, "dest_b");
1231
1232 BasicBlockSubGraph* subgraph = new BasicBlockSubGraph();
1233 subgraph->set_original_block(test_block_a);
1234 BlockGraph::Section* code_section = bgraph->FindOrAddSection(".text",
1235 0x60000000);
1236
1237 subgraph->AddBlockDescription("test_subgraph", code_section->name(),
1238 BlockGraph::CODE_BLOCK,
1239 code_section->id(), 1, 0);
1240
1241 BasicBlockSubGraph* subgraph_b = new BasicBlockSubGraph();
1242 subgraph_b->set_original_block(test_block_b);
1243
1244 subgraph_b->AddBlockDescription("test_subgraph", code_section->name(),
1245 BlockGraph::CODE_BLOCK,
1246 code_section->id(), 1, 0);
1247
1248
1249
1250 //set block id label
1251 auto test_block1_label = BlockGraph::Label(std::to_string(test_bb1_id),
1252 BlockGraph::CODE_LABEL);
1253 auto test_block2_label = BlockGraph::Label(std::to_string(test_bb2_id),
1254 BlockGraph::CODE_LABEL);
1255 //prepare id to label map
1256 tx_.id_to_label_[test_bb1_id] = test_block1_label;
1257 tx_.id_to_label_[test_bb2_id] = test_block2_label;
1258
1259
1260 //add chunks label
1261 for (uint32 i = 0; i< tx_.num_chunks_per_block; ++i) {
1262 std::string label = "n " + std::to_string(test_bb1_id)
1263 + " " + std::to_string(i);
1264 tx_.label_name_to_block_[label] = std::make_pair(test_block_a, 0);
1265 test_chunks.insert(test_chunks.begin(), ChunkInfo(test_bb1_id, 1, 1, i,0));
1266 }
1267 for (uint32 i = 0; i< tx_.num_chunks_per_block; ++i) {
1268 std::string label = "n " + std::to_string(test_bb2_id)
1269 + " " + std::to_string(i);
1270 tx_.label_name_to_block_[label] = std::make_pair(test_block_b, 0);
1271 test_chunks.insert(test_chunks.begin(), ChunkInfo(test_bb2_id, 1, 1, i,0));
1272 }
1273
1274 tx_.label_name_to_block_[std::to_string(test_bb1_id)] =
1275 std::make_pair(test_block_a, 0);
1276 tx_.label_name_to_block_[std::to_string(test_bb2_id)] =
1277 std::make_pair(test_block_b, 0);
1278
1279 uint64 test_checkee1_id = 2;
1280 uint64 test_checkee2_id = 3;
1281 std::map<uint64, int> test_checkee_map;
1282 test_checkee_map[test_checkee1_id] = 1;
1283 test_checkee_map[test_checkee2_id] = -1;
1284 tx_.checker_to_checkee_map_[test_bb1_id] = test_checkee_map;
1285 tx_.checker_to_checkee_map_[test_bb2_id] = test_checkee_map;
1286
1287 //prepare 20 chunks from these two checkers
1288 //20 n labels
1289 float test_chunk_coverage = 0.5;
1290 bool test_force_all = false;
1291 uint32 chunk_per_block = 0;
1292 auto chunk_map = tx_.GenerateChunkCombinations(test_chunks,
1293 test_chunk_coverage,
1294 test_force_all,
1295 &chunk_per_block
1296 );
1297
1298
1299 ASSERT_EQ(2, chunk_map.size());
1300 ASSERT_EQ(5, chunk_map[test_bb1_id].size());
1301 ASSERT_EQ(5, chunk_map[test_bb2_id].size());
1302 ASSERT_EQ(5, chunk_per_block);
1303
1304 //strictly picking all blocks
1305 test_chunk_coverage = 1;
1306 test_force_all = true;
1307 chunk_per_block = 0;
1308 chunk_map = tx_.GenerateChunkCombinations(test_chunks,
1309 test_chunk_coverage,
1310 test_force_all,
1311 &chunk_per_block);
1312
1313 ASSERT_EQ(2, chunk_map.size());
1314 ASSERT_EQ(10, chunk_map[test_bb1_id].size());
1315 ASSERT_EQ(10, chunk_map[test_bb2_id].size());
1316 ASSERT_EQ(10, chunk_per_block);
1317
1318 tx_.ResetTransform();
1319 delete bgraph;
1320 delete subgraph;
1321 delete subgraph_b;
1322 }
1323
1324 TEST_F(IntegrityCheckTransformTest, CheckRandomlySelectChecker) {
1325
1326 }
1327
1328 TEST_F(IntegrityCheckTransformTest, CheckIsIdInPartitionUnitMap) {
1329
1330 }
1331
1332 TEST_F(IntegrityCheckTransformTest, CheckFixAllCheckeesOfBasicBlock) {
1333
1334 }
1335
1336 TEST_F(IntegrityCheckTransformTest, CheckPatchInterBlockReferences) {
1337
1338 }
1339
1340 TEST_F(IntegrityCheckTransformTest, CheckPrecomputeHash) {
1341
1342 }
1343
1344 TEST_F(IntegrityCheckTransformTest, CheckAddReference) {
1345
1346 }
1347
1348 TEST_F(IntegrityCheckTransformTest, CheckGetBasicBlockIdByLabel) {
1349
1350 }
1351
1352 TEST_F(IntegrityCheckTransformTest, CheckTransformBasicBlockSubGraph) {
1353
1354 }
1355
1356
1357 TEST_F(IntegrityCheckTransformTest, CheckShouldProcessBlock) {
1358
1359 }
1360
1361 TEST_F(IntegrityCheckTransformTest, CheckProcessAllBlocks) {
1362
1363 }
1364
1365 TEST_F(IntegrityCheckTransformTest, CheckGenerateBasicBlockCombinations) {
1366
1367 }
1368
1369 TEST_F(IntegrityCheckTransformTest, CheckTransformBlockGraph) {
1370
1371 }
1372 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698