首页
论坛
专栏
课程

[原创] obfuscator-llvm-3.6.1 的 VS2017 win32 修正编译

tritium
2
2018-10-11 17:58 801
因考察 obf-llvm 对代码的展平化效果,想在win上编译obf-llvm。
根据官方简单的mkdir & cd & cmake & vs-compile 遭遇一些错误,需对源码做一些修正。
如下:

----------------
建立2017解决方案
----------------
根据官方说明用cmake通过源码建立2017解决方案
Download and install CMake. Version 2.8 is the minimum required.

Open a shell. Your development tools must be reachable from this shell through the PATH environment variable.

Create a directory for containing the build. It is not supported to build LLVM on the source directory. cd to this directory:

$ mkdir mybuilddir
$ cd mybuilddir
Execute this command on the shell replacing path/to/llvm/source/root with the path to the root of your LLVM source tree:

$ cmake path/to/llvm/source/root

这里我们解压释放的源码目录为obf_llvm_361
mkdir mybuilddir
cd mybuilddir
cmake ..\obf_llvm_361


-----------------------------------------------------------------
%ROOTDIR%\obf_llvm_361\lib\Transforms\Obfuscation\CryptoUtils.cpp
-----------------------------------------------------------------
编译解决方案会,执行会 提示 /dev/random 无法读取,window平台理所当然会出错。
由于源码目的市初始化16字节的key,我们改为srand,rand来完成key的随机初始化。 
#include <time.h>
void tritium_init_rand_key(char * buf,unsigned int buflen) {
	unsigned int i;
	srand(time(NULL));
	for (i = 0; i < buflen; i++) {
		buf[i] = char(rand() & 0xFF);
	}
}

#define __tritium__

void CryptoUtils::prng_seed() {
#ifdef __tritium__
	LLVMContext &ctx = llvm::getGlobalContext();
	tritium_init_rand_key(key, 16);
	DEBUG_WITH_TYPE("cryptoutils", dbgs() << "cryptoutils seeded with time srand and rand\n");
	memset(ctr, 0, 16);
	// Once the seed is there, we compute the
	// AES128 key-schedule
	aes_compute_ks(ks, key);
	seeded = true;
#else
  //原函数体代码
#endif // __tritium__
}


------------------------------------------------------
%ROOTDIR%\obf_llvm_361\lib\Support\Windows\Program.inc
------------------------------------------------------
对于已经在命令行运行了vcvarsall.bat初始化编译环境后,link.exe找不到,这部分代码检测文件是否可执行,
去不去都没啥影响,这里在检测该错误的过程去掉了,这里也去掉(方便确定的确市找不到文件的问题)。
  /* mask by tritium
  if (!sys::fs::can_execute(Program)) {
    if (ErrMsg)
      *ErrMsg = "program not executable";
    return false;
  }*/


-----------------------------------------------------
%ROOTDIR%\obf_llvm_361\tools\clang\lib\Driver\Job.cpp
-----------------------------------------------------
这部分代码会导致输入的提示,都是\\,而不是单个\,这里我们直接清除两行代码
  // Quote and escape. This isn't really complete, but good enough.
  OS << '"';
  while (const char c = *Arg++) {
    //if (c == '"' || c == '\\' || c == '$') // mask by tritium
    //  OS << '\\'; // mask by tritium
    OS << c;
  }
  OS << '"';

  
---------------------------------------------------------------
%ROOTDIR%\obf_llvm_361\tools\clang\lib\Driver\MSVCToolChain.cpp
---------------------------------------------------------------
这个是由于VS2017的编译环境初始化后,%VCINSTALLDIR%指向的VC目录下并没有bin目录
这里我们选择x86版link.exe,编译目标而言是x86版的目录
  // First check the environment variables that vsvars32.bat sets.
  llvm::Optional<std::string> VcInstallDir =
      llvm::sys::Process::GetEnv("VCINSTALLDIR");
  if (VcInstallDir.hasValue()) {
    BinDir = VcInstallDir.getValue();
    //llvm::sys::path::append(BinDir, "bin"); //modified by tritium
	llvm::sys::path::append(BinDir, "Tools\\MSVC\\14.12.25827\\bin\\Hostx86\\x86"); 

  
--------------------------------------------------------------------------
  //,data(原对象));
  ,reinterpret_cast<char*> (data(原对象)),原对象.size());// 构建 StringRef
--------------------------------------------------------------------------
这里是编译成功首先要解决的问题,上述是执行出错的问题。
由于EmitRecordWithBlob并没有只针对Vector<...>的原型,所以这里强制转换指针为char*后,再提供size参数,以便内部自行购置StringRef。
这个强制转换部分参考其它类似代码,size根据vector定义,初步也足够。
实际就是指定buf地址(char*),和bufsize。这里修改的严谨性没有再深入考察。
%ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(1517):  Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, reinterpret_cast<char*> (data(InputFileOffsets)),InputFileOffsets.size());// by add size param by tritium 2018/10/10
  %ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(1912):  Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, reinterpret_cast<char*>(data(SLocEntryOffsets)),SLocEntryOffsets.size()); // by tritium
  %ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(2237):	  reinterpret_cast<char*>(data(MacroOffsets)),MacroOffsets.size()); //by tritium
  %ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(2783):  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, reinterpret_cast<char*>(data(Decls)),Decls.size()); //by tritium
  %ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(2802):  Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, reinterpret_cast<char*>(data(TypeOffsets)),TypeOffsets.size());//by tritium
  %ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(2815):  Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, reinterpret_cast<char*>(data(DeclOffsets)),DeclOffsets.size()); // by tritium
  %ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(3520):	  reinterpret_cast<char*>(data(IdentifierOffsets)),IdentifierOffsets.size()); //by tritium
  %ROOTDIR%\obf_llvm_361\tools\clang\lib\Serialization\ASTWriter.cpp(4446):	  reinterpret_cast<char*>(data(NewGlobalDecls)),NewGlobalDecls.size()); // by tritium


编译成功后就可以在执行了Vs2017编译环境初始化批文件的cmd中用obf-llvm的clang进行展平化测试
clang.exe check_passwd.c -o check_passwd_flat.exe -mllvm -fla


参考链接

import base64

base64.b64decode('aHR0cHM6Ly9wYXBlci5zZWVidWcub3JnLzE5Mi8=')




[防守篇]2018看雪.TSRC CTF 挑战赛(团队赛)11月1日征题开启!

本主题帖已收到 1 次赞赏,累计¥1.00
最新回复 (4)
junkboy 2018-10-11 19:18
2

0

很实用
MaMy 2018-10-30 15:56
3

0

这个东西关键是 开了 100% 编译速度慢的xxxxxxx一样,开低了没啥用
hzqst 2 2018-10-31 11:06
4

0

MaMy 这个东西关键是 开了 100% 编译速度慢的xxxxxxx一样,开低了没啥用
不管开不开 肉眼识别都能看个大概,更何况有模拟器这种东西。。
MaMy 2018-10-31 13:57
5

0

hzqst 不管开不开 肉眼识别都能看个大概,更何况有模拟器这种东西。。
hhh,确实没毛病,不好用
混淆的代码相似度太高,肉眼识别还是强
最后于 2018-10-31 13:58 被MaMy编辑 ,原因:
返回