Libfuzzer 提供了两个 API 来开发自定义变异器。
size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed)
size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2, size_t Size2, uint8_t *Out, size_t MaxOutSize, unsigned int Seed)
Run Code Online (Sandbox Code Playgroud)
这些API应该如何使用?模糊器需要具有确定性。如何使用自定义变异器确保这一点?
我正在编写一个 LLVM 通行证,我需要找到可以定义加载指令读取的内存的每条指令。例如:
%x = alloca i32, align 4
store i32 123, i32* %x, align 4
%0 = load i32, i32* %x, align 4
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我想从加载指令到每个可能已经初始化/改变 %x 的指令。在这种情况下,只是之前的存储指令。我尝试使用 use-def 链,但这给了我定义内存的指令,也就是 alloca 指令。
bool runOnModule(Module &M) override {
for(Function &fun : M) {
for(BasicBlock &bb : fun) {
for(Instruction &instr : bb) {
if(isa<LoadInst>(instr)){
for (Use &U : instr.operands()) {
if (Instruction *Inst = dyn_cast<Instruction>(U)) {
errs() << *Inst << "\n";
}
}
}
}
}
}
return false;
}
};
Run Code Online (Sandbox Code Playgroud)
我怎样才能获得所有可能的存储指令,这些指令可以定义加载指令读取的内存?
我有一个从堆栈中分配内存的程序,如下所示:
%x = alloca i32, align 4
Run Code Online (Sandbox Code Playgroud)
在我的过程中,我想在运行时获得指向这个分配内存的实际内存指针。这应该是 %x。我如何在我的传球中获得指针?
Instruction* I;
if (AllocaInst* AI = dyn_cast<AllocaInst>(I)) {
//How to get %x?
}
Run Code Online (Sandbox Code Playgroud) 我想在运行时检查某些指令的值。因此,我创建了一个比较指令和一个分支指令,它们分支到“然后”基本块或“其他”基本块。但是,我不确定如何在条件分支之后插入创建的基本块,以及如何拆分现有基本块。
Instruction* someInst;
IRBuilder<> B(someInst);
Value* condition = B.CreateICmp(CmpInst::ICMP_UGT, someInst, someValue);
BasicBlock* thenBB = BasicBlock::Create(*ctx, "then");
BasicBlock* elseBB = BasicBlock::Create(*ctx, "else");
B.CreateCondBr(condition, thenBB, elseBB);
B.SetInsertPoint(thenBB);
//insert stuff
B.SetInsertPoint(elseBB);
//insert stuff
Run Code Online (Sandbox Code Playgroud)
如何在现有基本块的中间插入if / else?
我的应用程序使用一个非常大的文件,并从小窗口内的各种偏移量执行许多非常小的读取。我将直接文件读取替换为通过BufReader. 然后我使用进程监视器(来自 Sysinternals 套件)检查了操作系统执行的实际读取内容,似乎根本没有缓冲任何内容。更糟糕的是,它现在每次都会读取整个缓冲区容量,这使得性能变得更糟。
复制:
use std::fs::File;
use std::io::{BufReader, Read, Seek, SeekFrom};
fn main() {
let path = "data.bin";
let f = File::open(path).unwrap();
let mut r = BufReader::with_capacity(8 * 1024, f);
let mut buf = [0; 8];
r.seek(SeekFrom::Start(0)).unwrap();
r.read(&mut buf).unwrap();
r.seek(SeekFrom::Start(100)).unwrap();
r.read(&mut buf).unwrap();
r.seek(SeekFrom::Start(200)).unwrap();
r.read(&mut buf).unwrap();
}
Run Code Online (Sandbox Code Playgroud)
BufReader像这样的场景我该如何使用呢?
有人可以解释一下为什么连续两次释放导致崩溃,但释放第一个,然后是b,然后再次不会崩溃?
我知道free会将堆块插入双链接空闲列表中.释放两次会在空闲列表中两次插入相同的块.但为什么崩溃发生?
int *a = malloc(8);
int *b = malloc(8);
free(a);
// free(a); //Would crash!
free(b);
free(a); //No crash
Run Code Online (Sandbox Code Playgroud)