题目出自3W班9月第一题:编译llvm,动态调试Pass报告。老师的课件不是基于macos的,所以这篇文章算是自己踩坑之后的一个学习记录。
打开clion新建一个项目,先写一个demo:
尝试用你编译出来的clang来编译这个demo
编译报错:
重新编译
Pass
Cmakelists
编译
使用opt打印
Cmakelists
编译
使用
逆向
以编写ObfString为例
编译通过。
在代码中编写一个错误代码
编译
编写一个测试main.cpp
尝试调试
打开shell尝试编译
可以看出clang++的编译实际上是使用了clang-9做的编译,那么修改clion编译配置,尝试调试:
就可以调试了
$ .
/
clang
-
v
Android (
6454773
based on r365631c2) clang version
9.0
.
8
(https:
/
/
android.googlesource.com
/
toolchain
/
llvm
-
project
98c855489587874b2a325e7a516b99d838599c6f
) (based on LLVM
9.0
.
8svn
)
Target: x86_64
-
apple
-
darwin19.
6.0
Thread model: posix
InstalledDir:
/
Volumes
/
Work
/
SDK
/
AndroidSDK
/
ndk
/
21.3
.
6528147
/
toolchains
/
llvm
/
prebuilt
/
darwin
-
x86_64
/
bin
/
.
$ brew install cmake zlib ninja
$ https:
/
/
github.com
/
llvm
/
llvm
-
project
/
releases
-
G Ninja
-
DLLVM_ENABLE_PROJECTS
=
"clang"
$ ninja
-
j8
$ .
/
clang
-
v
Android (
6454773
based on r365631c2) clang version
9.0
.
8
(https:
/
/
android.googlesource.com
/
toolchain
/
llvm
-
project
98c855489587874b2a325e7a516b99d838599c6f
) (based on LLVM
9.0
.
8svn
)
Target: x86_64
-
apple
-
darwin19.
6.0
Thread model: posix
InstalledDir:
/
Volumes
/
Work
/
SDK
/
AndroidSDK
/
ndk
/
21.3
.
6528147
/
toolchains
/
llvm
/
prebuilt
/
darwin
-
x86_64
/
bin
/
.
$ brew install cmake zlib ninja
$ https:
/
/
github.com
/
llvm
/
llvm
-
project
/
releases
-
G Ninja
-
DLLVM_ENABLE_PROJECTS
=
"clang"
$ ninja
-
j8
void test(){
printf(
"this is Test!\n"
);
}
void test01(){
printf(
"test01\n"
);
}
int
main() {
test();
test01();
return
0
;
}
void test(){
printf(
"this is Test!\n"
);
}
void test01(){
printf(
"test01\n"
);
}
int
main() {
test();
test01();
return
0
;
}
$ export PATH
=
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
bin
/
:$PATH
$ clang main.cpp
-
o main_clang
$ export PATH
=
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
bin
/
:$PATH
$ clang main.cpp
-
o main_clang
$ clang main.cpp
-
o main_clang
clang
-
9
: error: no such
file
or
directory:
'main.cpp'
clang
-
9
: error: no
input
files
$ export SDKROOT
=
$(xcrun
-
-
sdk macosx
-
-
show
-
sdk
-
path)
$ clang main.cpp
-
o main_clang
clang
-
9
: error: no such
file
or
directory:
'main.cpp'
clang
-
9
: error: no
input
files
$ export SDKROOT
=
$(xcrun
-
-
sdk macosx
-
-
show
-
sdk
-
path)
$ clang main.c
-
o main_clang
$ .
/
main_clang
this
is
Test!
test01
$ clang
-
emit
-
llvm main.c
-
S
-
o main.ll
$ llvm
-
as main.ll
-
o main.bc
$ clang main.c
-
o main_clang
$ .
/
main_clang
this
is
Test!
test01
$ clang
-
emit
-
llvm main.c
-
S
-
o main.ll
$ llvm
-
as main.ll
-
o main.bc
/
/
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
lib
/
Transforms
/
EncodeFunctionName
/
EncodeFunctionName.cpp
using namespace llvm;
namespace llvm {
struct EncodeFunctionName : public FunctionPass {
static char
ID
;
/
/
Pass identification, replacement
for
typeid
EncodeFunctionName() : FunctionPass(
ID
) {};
bool
runOnFunction(Function &F) override {
errs() <<
"EncodeFunctionName"
;
errs().write_escaped(F.getName()) <<
'\n'
;
return
false;
}
};
}
char EncodeFunctionName::
ID
=
0
;
static RegisterPass<EncodeFunctionName> X(
"encode"
,
"Hello EncodeFunctionName Pass"
);
static llvm::RegisterStandardPasses Y(
llvm::PassManagerBuilder::EP_EarlyAsPossible,
[](const llvm::PassManagerBuilder &Builder,
llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
/
/
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
lib
/
Transforms
/
EncodeFunctionName
/
EncodeFunctionName.cpp
using namespace llvm;
namespace llvm {
struct EncodeFunctionName : public FunctionPass {
static char
ID
;
/
/
Pass identification, replacement
for
typeid
EncodeFunctionName() : FunctionPass(
ID
) {};
bool
runOnFunction(Function &F) override {
errs() <<
"EncodeFunctionName"
;
errs().write_escaped(F.getName()) <<
'\n'
;
return
false;
}
};
}
char EncodeFunctionName::
ID
=
0
;
static RegisterPass<EncodeFunctionName> X(
"encode"
,
"Hello EncodeFunctionName Pass"
);
static llvm::RegisterStandardPasses Y(
llvm::PassManagerBuilder::EP_EarlyAsPossible,
[](const llvm::PassManagerBuilder &Builder,
llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
add_llvm_library( LLVMEncodeFunctionName MODULE BUILDTREE_ONLY
EncodeFunctionName.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
add_llvm_library( LLVMEncodeFunctionName MODULE BUILDTREE_ONLY
EncodeFunctionName.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
$ cd
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
$ ninja LLVMEncodeFunctionName
$ cd
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
$ ninja LLVMEncodeFunctionName
$ opt
-
load
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
lib
/
LLVMEncodeFunctionName.dylib
-
encode main.ll
-
o main.bc
$ opt
-
load
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
lib
/
LLVMEncodeFunctionName.dylib
-
encode main.ll
-
o main.bc
/
/
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
lib
/
Transforms
/
EncodeFunctionName
/
EncodeFunctionName.cpp
using namespace llvm;
namespace llvm {
struct EncodeFunctionName : public FunctionPass {
static char
ID
;
/
/
Pass identification, replacement
for
typeid
EncodeFunctionName() : FunctionPass(
ID
) {};
bool
runOnFunction(Function &F) override {
errs() <<
"EncodeFunctionName: "
<< F.getName() <<
" -> "
;
if
(F.getName().compare(
"main"
) !
=
0
){
llvm::MD5 Hasher;
llvm::MD5::MD5Result
Hash
;
Hasher.update(F.getName());
Hasher.update(
"NewFunctionName"
);
Hasher.final(
Hash
);
SmallString<
32
> HexString;
llvm::MD5::stringifyResult(
Hash
, HexString);
F.setName(HexString);
}
errs().write_escaped(F.getName()) <<
'\n'
;
return
false;
}
};
}
char EncodeFunctionName::
ID
=
0
;
static RegisterPass<EncodeFunctionName> X(
"encode"
,
"Hello EncodeFunctionName Pass"
);
static llvm::RegisterStandardPasses Y(
llvm::PassManagerBuilder::EP_EarlyAsPossible,
[](const llvm::PassManagerBuilder &Builder,
llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
/
/
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
lib
/
Transforms
/
EncodeFunctionName
/
EncodeFunctionName.cpp
using namespace llvm;
namespace llvm {
struct EncodeFunctionName : public FunctionPass {
static char
ID
;
/
/
Pass identification, replacement
for
typeid
EncodeFunctionName() : FunctionPass(
ID
) {};
bool
runOnFunction(Function &F) override {
errs() <<
"EncodeFunctionName: "
<< F.getName() <<
" -> "
;
if
(F.getName().compare(
"main"
) !
=
0
){
llvm::MD5 Hasher;
llvm::MD5::MD5Result
Hash
;
Hasher.update(F.getName());
Hasher.update(
"NewFunctionName"
);
Hasher.final(
Hash
);
SmallString<
32
> HexString;
llvm::MD5::stringifyResult(
Hash
, HexString);
F.setName(HexString);
}
errs().write_escaped(F.getName()) <<
'\n'
;
return
false;
}
};
}
char EncodeFunctionName::
ID
=
0
;
static RegisterPass<EncodeFunctionName> X(
"encode"
,
"Hello EncodeFunctionName Pass"
);
static llvm::RegisterStandardPasses Y(
llvm::PassManagerBuilder::EP_EarlyAsPossible,
[](const llvm::PassManagerBuilder &Builder,
llvm::legacy::PassManagerBase &PM) { PM.add(new EncodeFunctionName()); });
add_llvm_library( LLVMEncodeFunctionName MODULE BUILDTREE_ONLY
EncodeFunctionName.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
add_llvm_library( LLVMEncodeFunctionName MODULE BUILDTREE_ONLY
EncodeFunctionName.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
$ cd
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
$ ninja LLVMEncodeFunctionName
[
2
/
2
] Linking CXX shared module lib
/
LLVMEncodeFunctionName.dylib
$ cd
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
$ ninja LLVMEncodeFunctionName
[
2
/
2
] Linking CXX shared module lib
/
LLVMEncodeFunctionName.dylib
$ export PATH
=
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
bin
/
:$PATH
$ clang
-
-
version
clang version
9.0
.
1
Target: x86_64
-
apple
-
darwin19.
6.0
Thread model: posix
InstalledDir:
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
bin
$ clang
-
emit
-
llvm main.c
-
S
-
o main.ll
$ opt
-
load
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
lib
/
LLVMEncodeFunctionName.dylib
-
encode main.ll
-
o main.bc
EncodeFunctionName: test
-
>
5087472e3f661e2a53ecdb4d8dc398a7
EncodeFunctionName: test01
-
> e63ae3cc6d7f9892993496b04573c87c
EncodeFunctionName: main
-
> main
$ clang main.bc
-
o main_clang
$ export PATH
=
/
Volumes
/
Work
/
CLion
/
Projects
/
llvm
-
project
-
llvmorg
-
9.0
.
1
/
llvm
/
cmake
-
build
-
debug
/
bin
/
:$PATH
$ clang
-
-
version
clang version
9.0
.
1
Target: x86_64
-
apple
-
darwin19.
6.0
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!