@@ -170,14 +170,17 @@ llvmGetPassPluginInfo() {
170
170
#else
171
171
char CmpLogRoutines::ID = 0 ;
172
172
#endif
173
+ #include < iostream>
173
174
174
175
bool CmpLogRoutines::hookRtns (Module &M) {
175
- std::vector<CallInst *> calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC;
176
- LLVMContext &C = M.getContext ();
176
+ std::vector<CallInst *> calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC,
177
+ Memcmp, Strcmp, Strncmp;
178
+ LLVMContext &C = M.getContext ();
177
179
178
180
Type *VoidTy = Type::getVoidTy (C);
179
181
// PointerType *VoidPtrTy = PointerType::get(VoidTy, 0);
180
182
IntegerType *Int8Ty = IntegerType::getInt8Ty (C);
183
+ IntegerType *Int64Ty = IntegerType::getInt64Ty (C);
181
184
PointerType *i8PtrTy = PointerType::get (Int8Ty, 0 );
182
185
183
186
#if LLVM_VERSION_MAJOR < 9
@@ -269,6 +272,60 @@ bool CmpLogRoutines::hookRtns(Module &M) {
269
272
FunctionCallee cmplogGccStdC = c4;
270
273
#endif
271
274
275
+ #if LLVM_VERSION_MAJOR >= 9
276
+ FunctionCallee
277
+ #else
278
+ Constant *
279
+ #endif
280
+ c5 = M.getOrInsertFunction (" __cmplog_rtn_hook_n" , VoidTy, i8PtrTy,
281
+ i8PtrTy, Int64Ty
282
+ #if LLVM_VERSION_MAJOR < 5
283
+ ,
284
+ NULL
285
+ #endif
286
+ );
287
+ #if LLVM_VERSION_MAJOR >= 9
288
+ FunctionCallee cmplogHookFnN = c5;
289
+ #else
290
+ Function *cmplogHookFnN = cast<Function>(c5);
291
+ #endif
292
+
293
+ #if LLVM_VERSION_MAJOR >= 9
294
+ FunctionCallee
295
+ #else
296
+ Constant *
297
+ #endif
298
+ c6 = M.getOrInsertFunction (" __cmplog_rtn_hook_strn" , VoidTy, i8PtrTy,
299
+ i8PtrTy, Int64Ty
300
+ #if LLVM_VERSION_MAJOR < 5
301
+ ,
302
+ NULL
303
+ #endif
304
+ );
305
+ #if LLVM_VERSION_MAJOR >= 9
306
+ FunctionCallee cmplogHookFnStrN = c6;
307
+ #else
308
+ Function *cmplogHookFnStrN = cast<Function>(c6);
309
+ #endif
310
+
311
+ #if LLVM_VERSION_MAJOR >= 9
312
+ FunctionCallee
313
+ #else
314
+ Constant *
315
+ #endif
316
+ c7 = M.getOrInsertFunction (" __cmplog_rtn_hook_str" , VoidTy, i8PtrTy,
317
+ i8PtrTy
318
+ #if LLVM_VERSION_MAJOR < 5
319
+ ,
320
+ NULL
321
+ #endif
322
+ );
323
+ #if LLVM_VERSION_MAJOR >= 9
324
+ FunctionCallee cmplogHookFnStr = c7;
325
+ #else
326
+ Function *cmplogHookFnStr = cast<Function>(c7);
327
+ #endif
328
+
272
329
/* iterate over all functions, bbs and instruction and add suitable calls */
273
330
for (auto &F : M) {
274
331
if (isIgnoreFunction (&F)) { continue ; }
@@ -283,12 +340,87 @@ bool CmpLogRoutines::hookRtns(Module &M) {
283
340
if (callInst->getCallingConv () != llvm::CallingConv::C) { continue ; }
284
341
285
342
FunctionType *FT = Callee->getFunctionType ();
343
+ std::string FuncName = Callee->getName ().str ();
286
344
287
345
bool isPtrRtn = FT->getNumParams () >= 2 &&
288
346
!FT->getReturnType ()->isVoidTy () &&
289
347
FT->getParamType (0 ) == FT->getParamType (1 ) &&
290
348
FT->getParamType (0 )->isPointerTy ();
291
349
350
+ bool isPtrRtnN = FT->getNumParams () >= 3 &&
351
+ !FT->getReturnType ()->isVoidTy () &&
352
+ FT->getParamType (0 ) == FT->getParamType (1 ) &&
353
+ FT->getParamType (0 )->isPointerTy () &&
354
+ FT->getParamType (2 )->isIntegerTy ();
355
+ if (isPtrRtnN) {
356
+ auto intTyOp =
357
+ dyn_cast<IntegerType>(callInst->getArgOperand (2 )->getType ());
358
+ if (intTyOp) {
359
+ if (intTyOp->getBitWidth () != 32 &&
360
+ intTyOp->getBitWidth () != 64 ) {
361
+ isPtrRtnN = false ;
362
+ }
363
+ }
364
+ }
365
+
366
+ bool isMemcmp =
367
+ (!FuncName.compare (" memcmp" ) || !FuncName.compare (" bcmp" ) ||
368
+ !FuncName.compare (" CRYPTO_memcmp" ) ||
369
+ !FuncName.compare (" OPENSSL_memcmp" ) ||
370
+ !FuncName.compare (" memcmp_const_time" ) ||
371
+ !FuncName.compare (" memcmpct" ));
372
+ isMemcmp &= FT->getNumParams () == 3 &&
373
+ FT->getReturnType ()->isIntegerTy (32 ) &&
374
+ FT->getParamType (0 )->isPointerTy () &&
375
+ FT->getParamType (1 )->isPointerTy () &&
376
+ FT->getParamType (2 )->isIntegerTy ();
377
+
378
+ bool isStrcmp =
379
+ (!FuncName.compare (" strcmp" ) || !FuncName.compare (" xmlStrcmp" ) ||
380
+ !FuncName.compare (" xmlStrEqual" ) ||
381
+ !FuncName.compare (" g_strcmp0" ) ||
382
+ !FuncName.compare (" curl_strequal" ) ||
383
+ !FuncName.compare (" strcsequal" ) ||
384
+ !FuncName.compare (" strcasecmp" ) ||
385
+ !FuncName.compare (" stricmp" ) ||
386
+ !FuncName.compare (" ap_cstr_casecmp" ) ||
387
+ !FuncName.compare (" OPENSSL_strcasecmp" ) ||
388
+ !FuncName.compare (" xmlStrcasecmp" ) ||
389
+ !FuncName.compare (" g_strcasecmp" ) ||
390
+ !FuncName.compare (" g_ascii_strcasecmp" ) ||
391
+ !FuncName.compare (" Curl_strcasecompare" ) ||
392
+ !FuncName.compare (" Curl_safe_strcasecompare" ) ||
393
+ !FuncName.compare (" cmsstrcasecmp" ) ||
394
+ !FuncName.compare (" strstr" ) ||
395
+ !FuncName.compare (" g_strstr_len" ) ||
396
+ !FuncName.compare (" ap_strcasestr" ) ||
397
+ !FuncName.compare (" xmlStrstr" ) ||
398
+ !FuncName.compare (" xmlStrcasestr" ) ||
399
+ !FuncName.compare (" g_str_has_prefix" ) ||
400
+ !FuncName.compare (" g_str_has_suffix" ));
401
+ isStrcmp &=
402
+ FT->getNumParams () == 2 && FT->getReturnType ()->isIntegerTy (32 ) &&
403
+ FT->getParamType (0 ) == FT->getParamType (1 ) &&
404
+ FT->getParamType (0 ) == IntegerType::getInt8PtrTy (M.getContext ());
405
+
406
+ bool isStrncmp = (!FuncName.compare (" strncmp" ) ||
407
+ !FuncName.compare (" xmlStrncmp" ) ||
408
+ !FuncName.compare (" curl_strnequal" ) ||
409
+ !FuncName.compare (" strncasecmp" ) ||
410
+ !FuncName.compare (" strnicmp" ) ||
411
+ !FuncName.compare (" ap_cstr_casecmpn" ) ||
412
+ !FuncName.compare (" OPENSSL_strncasecmp" ) ||
413
+ !FuncName.compare (" xmlStrncasecmp" ) ||
414
+ !FuncName.compare (" g_ascii_strncasecmp" ) ||
415
+ !FuncName.compare (" Curl_strncasecompare" ) ||
416
+ !FuncName.compare (" g_strncasecmp" ));
417
+ isStrncmp &= FT->getNumParams () == 3 &&
418
+ FT->getReturnType ()->isIntegerTy (32 ) &&
419
+ FT->getParamType (0 ) == FT->getParamType (1 ) &&
420
+ FT->getParamType (0 ) ==
421
+ IntegerType::getInt8PtrTy (M.getContext ()) &&
422
+ FT->getParamType (2 )->isIntegerTy ();
423
+
292
424
bool isGccStdStringStdString =
293
425
Callee->getName ().find (" __is_charIT_EE7__value" ) !=
294
426
std::string::npos &&
@@ -336,11 +468,17 @@ bool CmpLogRoutines::hookRtns(Module &M) {
336
468
*/
337
469
338
470
if (isGccStdStringCString || isGccStdStringStdString ||
339
- isLlvmStdStringStdString || isLlvmStdStringCString) {
340
- isPtrRtn = false ;
471
+ isLlvmStdStringStdString || isLlvmStdStringCString || isMemcmp ||
472
+ isStrcmp || isStrncmp) {
473
+ isPtrRtnN = isPtrRtn = false ;
341
474
}
342
475
476
+ if (isPtrRtnN) { isPtrRtn = false ; }
477
+
343
478
if (isPtrRtn) { calls.push_back (callInst); }
479
+ if (isMemcmp || isPtrRtnN) { Memcmp.push_back (callInst); }
480
+ if (isStrcmp) { Strcmp.push_back (callInst); }
481
+ if (isStrncmp) { Strncmp.push_back (callInst); }
344
482
if (isGccStdStringStdString) { gccStdStd.push_back (callInst); }
345
483
if (isGccStdStringCString) { gccStdC.push_back (callInst); }
346
484
if (isLlvmStdStringStdString) { llvmStdStd.push_back (callInst); }
@@ -351,9 +489,9 @@ bool CmpLogRoutines::hookRtns(Module &M) {
351
489
}
352
490
353
491
if (!calls.size () && !gccStdStd.size () && !gccStdC.size () &&
354
- !llvmStdStd.size () && !llvmStdC.size ()) {
492
+ !llvmStdStd.size () && !llvmStdC.size () && !Memcmp.size () &&
493
+ Strcmp.size () && Strncmp.size ())
355
494
return false ;
356
- }
357
495
358
496
for (auto &callInst : calls) {
359
497
Value *v1P = callInst->getArgOperand (0 ), *v2P = callInst->getArgOperand (1 );
@@ -372,6 +510,67 @@ bool CmpLogRoutines::hookRtns(Module &M) {
372
510
// errs() << callInst->getCalledFunction()->getName() << "\n";
373
511
}
374
512
513
+ for (auto &callInst : Memcmp) {
514
+ Value *v1P = callInst->getArgOperand (0 ), *v2P = callInst->getArgOperand (1 ),
515
+ *v3P = callInst->getArgOperand (2 );
516
+
517
+ IRBuilder<> IRB (callInst->getParent ());
518
+ IRB.SetInsertPoint (callInst);
519
+
520
+ std::vector<Value *> args;
521
+ Value *v1Pcasted = IRB.CreatePointerCast (v1P, i8PtrTy);
522
+ Value *v2Pcasted = IRB.CreatePointerCast (v2P, i8PtrTy);
523
+ Value *v3Pbitcast = IRB.CreateBitCast (
524
+ v3P, IntegerType::get (C, v3P->getType ()->getPrimitiveSizeInBits ()));
525
+ Value *v3Pcasted =
526
+ IRB.CreateIntCast (v3Pbitcast, IntegerType::get (C, 64 ), false );
527
+ args.push_back (v1Pcasted);
528
+ args.push_back (v2Pcasted);
529
+ args.push_back (v3Pcasted);
530
+
531
+ IRB.CreateCall (cmplogHookFnN, args);
532
+
533
+ // errs() << callInst->getCalledFunction()->getName() << "\n";
534
+ }
535
+
536
+ for (auto &callInst : Strcmp) {
537
+ Value *v1P = callInst->getArgOperand (0 ), *v2P = callInst->getArgOperand (1 );
538
+
539
+ IRBuilder<> IRB (callInst->getParent ());
540
+ IRB.SetInsertPoint (callInst);
541
+ std::vector<Value *> args;
542
+ Value *v1Pcasted = IRB.CreatePointerCast (v1P, i8PtrTy);
543
+ Value *v2Pcasted = IRB.CreatePointerCast (v2P, i8PtrTy);
544
+ args.push_back (v1Pcasted);
545
+ args.push_back (v2Pcasted);
546
+
547
+ IRB.CreateCall (cmplogHookFnStr, args);
548
+
549
+ // errs() << callInst->getCalledFunction()->getName() << "\n";
550
+ }
551
+
552
+ for (auto &callInst : Strncmp) {
553
+ Value *v1P = callInst->getArgOperand (0 ), *v2P = callInst->getArgOperand (1 ),
554
+ *v3P = callInst->getArgOperand (2 );
555
+
556
+ IRBuilder<> IRB (callInst->getParent ());
557
+ IRB.SetInsertPoint (callInst);
558
+ std::vector<Value *> args;
559
+ Value *v1Pcasted = IRB.CreatePointerCast (v1P, i8PtrTy);
560
+ Value *v2Pcasted = IRB.CreatePointerCast (v2P, i8PtrTy);
561
+ Value *v3Pbitcast = IRB.CreateBitCast (
562
+ v3P, IntegerType::get (C, v3P->getType ()->getPrimitiveSizeInBits ()));
563
+ Value *v3Pcasted =
564
+ IRB.CreateIntCast (v3Pbitcast, IntegerType::get (C, 64 ), false );
565
+ args.push_back (v1Pcasted);
566
+ args.push_back (v2Pcasted);
567
+ args.push_back (v3Pcasted);
568
+
569
+ IRB.CreateCall (cmplogHookFnStrN, args);
570
+
571
+ // errs() << callInst->getCalledFunction()->getName() << "\n";
572
+ }
573
+
375
574
for (auto &callInst : gccStdStd) {
376
575
Value *v1P = callInst->getArgOperand (0 ), *v2P = callInst->getArgOperand (1 );
377
576
0 commit comments