稻城| 西藏| 岳池| 辽中| 营山| 班戈| 北京| 新宁| 郧西| 浏阳| 刚察| 谢家集| 新郑| 博野| 萍乡| 张家口| 罗江| 师宗| 阳高| 宿豫| 彰武| 渭南| 台安| 钦州| 喀喇沁左翼| 涿鹿| 九江市| 九江县| 保康| 霍林郭勒| 赣县| 广东| 金华| 松原| 香港| 浦口| 兴仁| 雷山| 宾川| 溧阳| 沁水| 张家港| 台江| 改则| 关岭| 珲春| 美姑| 秀山| 武陵源| 黄山区| 莘县| 吴忠| 靖边| 长子| 开县| 永泰| 清水河| 剑阁| 普兰店| 白沙| 墨玉| 深泽| 突泉| 巴彦淖尔| 甘孜| 扶沟| 邗江| 广昌| 思茅| 德州| 竹溪| 吉隆| 南木林| 房山| 丹东| 汉口| 东至| 临汾| 康保| 扎兰屯| 武陵源| 湘乡| 薛城| 汨罗| 澄迈| 索县| 吉利| 商城| 贵溪| 宁德| 文县| 项城| 庆元| 衢江| 衡山| 信宜| 麻山| 丰台| 郑州| 吴中| 南京| 千阳| 磁县| 遂平| 崇明| 潮州| 丽水| 南宫| 盈江| 根河| 加格达奇| 黎平| 麻山| 册亨| 信宜| 乌什| 栾城| 化德| 中阳| 聂拉木| 青白江| 沧县| 湖口| 莱西| 茂名| 新巴尔虎右旗| 岢岚| 饶阳| 酒泉| 瑞丽| 扶沟| 滴道| 凤县| 襄汾| 犍为| 三水| 卢龙| 天津| 夹江| 张湾镇| 新洲| 泾源| 永川| 江城| 水富| 余庆| 丹徒| 慈溪| 大余| 岳西| 武宣| 色达| 上饶县| 宿豫| 交城| 阳春| 临武| 延庆| 克山| 渭南| 安顺| 清水| 珊瑚岛| 承德市| 吉利| 河北| 贵州| 安福| 新晃| 灌阳| 迁安| 成都| 皮山| 慈溪| 石狮| 郧西| 甘洛| 互助| 利辛| 曲靖| 汕头| 南召| 宽城| 博山| 唐海| 怀来| 亳州| 无锡| 九龙| 应城| 抚松| 宁阳| 延吉| 大竹| 长垣| 丹江口| 京山| 霍城| 浮梁| 安乡| 新河| 盘锦| 肥西| 玛曲| 镶黄旗| 闽清| 姚安| 富民| 鄄城| 庆阳| 吉林| 礼县| 平原| 偏关| 陆川| 弓长岭| 浪卡子| 江夏| 赤城| 清徐| 长白山| 清徐| 白银| 海盐| 珲春| 太白| 咸宁| 于田| 札达| 孝感| 天镇| 聊城| 稷山| 邹平| 洮南| 惠东| 乌兰察布| 类乌齐| 东兴| 平南| 延长| 怀集| 贵港| 辽阳县| 吴江| 襄阳| 沅陵| 潜江| 吕梁| 西山| 乾安| 广平| 图们| 江安| 伊宁县| 攀枝花| 凤庆| 麻栗坡| 莲花| 浦城| 伊吾| 顺昌| 铁力| 龙山| 博狗体育

雪佛龙石油公司意向售旗下25亿美元油沙田资产

2018-04-23 02:08 来源:商都网

  雪佛龙石油公司意向售旗下25亿美元油沙田资产

  优博平台官网这里自永乐七年五月始作长陵,到明朝最后一帝崇祯葬入思陵止,其间230多年,先后修建了十三座皇帝陵墓、七座妃子墓、一座太监墓。后随佛教盛行,佛祖成道日与腊日融合,在佛教领域被称为“法宝节”。

日新月异鸡报晓;岁吉年祥狗看门。过了中午还找乐子的人是一个比被他取笑的人还大的傻瓜。

  9、谷物全麦面包中的锌物质对于人体的免疫系统是非常有好处的。需要注意的是愚人节这天玩笑只能开到中午12点之前,这是约定俗成的严格规定,过了钟点还开玩笑的人会立刻碰钉子,自找没趣儿,称为比被他取笑的人还要大的傻瓜。

  近期动作冒险片《古墓丽影:源起之战》强势热映,影片中主角深入失落千年的异域遗迹,发掘古国墓葬中的神秘力量,引得影迷大呼刺激。作者:张屹土耳其未遂政变后,土俄关系快速改善同时土美关系长期陷入低谷,俄罗斯以土耳其为重要依托加大叙东部军事行动力度。

有时它是路边的一只小狗,热闹是我们的,自在是它的。

  不过樱花花期会因而出现较大变化,去年武汉大学的樱花花期长达23天,2012年却仅有短短10天。

  的可是一直备受大家的关注,今天的深圳晴天多云,最度达25摄氏度,明天开始湿度将升高,未来一周都是晴朗天气。如果说之前他大骂特朗普白痴是下台的外在因素之一,那么中东的态度就是他下台的内在原因,就像之前特朗普说过的,他辞退蒂勒森并不是因为两人性格不同,而是因为政见不一样,特别是核协议这个问题,这也从侧面证明中东在其中确实起到很大作用。

  并且一举成为了叙利亚政府军在大马士革地区的最大威胁。

  美国《防务新闻》网等媒体最近直接指出,美国向乌克兰提供武器是一种错误。他们依旧在四月一日这天互赠礼物,组织庆祝新年的活动。

  不过从上海交通委真实,这个是不实消息。

  吉祥坊官方网站电脑版据了解,西山国家森林公园里最为著名的“西山晴雪”景观将于下周呈现在市民游客眼前。

  因农历鸡年有一个“闰6月”,因此,2017农历鸡年有384天,这个鸡年共有6个小月,每月29天和7个大月,每月30天,一年共有384天。白温回升快,未来几天北方最也将明显回升,最低气温10℃线将逐步向北推进至华北北部,像是济南,27日的最低气温可能突破2字头。

  博狗网址 银河赌城 申博太阳城官网

  雪佛龙石油公司意向售旗下25亿美元油沙田资产

 
责编:

吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3665|回复: 43
上一主题 下一主题

雪佛龙石油公司意向售旗下25亿美元油沙田资产

  [复制链接]
跳转到指定楼层
楼主
发表于 2018-4-9 15:04 | 只看该作者 回帖奖励 |倒序浏览
本帖最后由 NavilleZhang 于 2018-4-10 13:11 编辑

我决定把自留地里的一些文章搬运过来,纯给新手入门使用。稳定的开源混淆请参见 HikariObfuscator/Hikari
注:如同另一篇一样,这只是个演示向的教学,这个实现的问题会在末尾写出。实际使用请直接使用Hikari的实现。 原来的帖子下面还有一些其他的讨论,来玩呀。

零基础的入门贴的入门指南(如果你完全没有接触过LLVM的话这是必读) : http://www.alonemonkey.com.cfporn.com/2017/06/02/writing-an-llvm-pass/

前置要求

  • 对C++/C的入门知识
  • 高中及以上的英语水平
  • 一台电脑
  • 对命令行的基础使用
  • 对垃圾代码的忍耐能力
  • 会用Google
  • 会下载安装编译LLVM
金沙城中心 1989年4月15至5月5日,首届北京植物园桃花节举办,为期20天,共有6大类、40多种桃花。

这篇文章来源于我在实现自己的产品级混淆器中遇到的现有实现方案的各种问题,编写过程中可能会出现各种中英文混用导致无法Google到相关信息,另外我是个非常糟糕的老师,文章的各种问题还望海涵。

基础知识

  • 每个源码文件(大致上)对应一个翻译单元(Translation Unit), LLVM体系中每个Module对应一个翻译单元
  • Module是LLVM中间表示的最外层封装,所有的函数,变量,元数据等等全部封装在对应的Module中
  • (几乎)所有跟LLVM中间表示有关的数据类型都继承自llvm::Value 下文中所有的值指代的都是该类所有子类的统称
  • 字符串在LLVM中间表示里用一个常数数组实现。(但有对应的基于字符串的构造方法)
  • 每个函数由一个或多个基本块组成,每个基本块有一个结束指令用于改变控制流。调用其他函数,跳转至其他基本块,返回void或其他值的指令都属于此列。参见 LLVM Language Reference Manual

实现设计

设计上我们搜索所有函数内对全局变量的调用,判断是否为常数数组,如是则在函数的起始位置插入解密函数,在函数的结尾插入加密函数。这点上优于现有的上海交通大学密码与计算机安全实验室的实现方案Armariris,对于该方案的详细分析可以参见我的博客

正文

首先我们导出一份任意包含字符串的源码的中间表示供参考。
我们使用的源码是如下我手动构造的示例文件:

#import <Foundation/Foundation.h>
#import <dlfcn.h>
#import <objc/runtime.h>
static char* foo1="GlobalVariable";
int main(){
  printf("你好世界");
  NSLog(@"你好");
  return 0;
}

在我的macOS上使用Apple的clang:

clang -S -emit-llvm SOURCE.mm

产生了如下的LLVM中间表示:

; ModuleID = 'hw.m'
source_filename = "hw.m"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.13.0"

%struct.__NSConstantString_tag = type { i32*, i32, i8*, i64 }

@.str = private unnamed_addr constant [13 x i8] c"\E4\BD\A0\E5\A5\BD\E4\B8\96\E7\95\8C\00", align 1
@__CFConstantStringClassReference = external global [0 x i32]
@.str.1 = private unnamed_addr constant [3 x i16] [i16 20320, i16 22909, i16 0], section "__TEXT,__ustring", align 2
@_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast ([3 x i16]* @.str.1 to i8*), i64 2 }, section "__DATA,__cfstring", align 8

; Function Attrs: noinline optnone ssp uwtable
define i32 home.php?mod=space&uid=443615 #0 {
  %1 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0))
  notail call void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to i8*))
  ret i32 0
}

declare i32 @printf(i8*, ...) #1

declare void @NSLog(i8*, ...) #1

attributes #0 = { noinline optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6}
!llvm.ident = !{!7}

!0 = !{i32 1, !"Objective-C Version", i32 2}
!1 = !{i32 1, !"Objective-C Image Info Version", i32 0}
!2 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
!3 = !{i32 4, !"Objective-C Garbage Collection", i32 0}
!4 = !{i32 1, !"Objective-C Class Properties", i32 64}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{i32 7, !"PIC Level", i32 2}
!7 = !{!"clang version 6.0.0 (trunk 318965) (llvm/trunk 318964)"}

基础知识: LLVM的函数分为declare和definition两种。如上所示,declare指的是实现在当前翻译单元外的函数,definition反之。

有了这些知识,接下来我们先搭建我们的Pass的大致结构.注意KeyMap是我们用于存储变量和对应Key的映射表:

/*
*  LLVM StringEncryption Pass
*  https://mayuyu.io
*  GPL V3 Licensed
*/
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
#include <string>
/*
  Unlike Armariris which inject decrytion code at llvm.global_ctors.
  We try to find the containing Function of Users referencing our string GV.
  Then we search for terminators.
  We insert decryption code at begining or the function and encrypt it back at
  terminators

  For Users where we cant find a Function, we then inject decryption codes at
  ctors
*/
/*
Status: Currently we only handle strings passed in directly.
GV strings are not properly handled
*/
using namespace llvm;
using namespace std;
namespace llvm {
struct StringEncryption : public ModulePass {
  static char ID;
  map<GlobalVariable * /*Value*/, Constant * /*Key*/>
      keymap; // Map GV to keys for encryption
  StringEncryption() : ModulePass(ID) {}
  StringRef getPassName() const override {
    return StringRef("StringEncryption");
  }
  bool runOnModule(Module &M) override {
    // in runOnModule. We simple iterate function list and dispatch functions
    // to handlers
    for (Module::iterator iter = M.begin(); iter != M.end(); iter++) {
      Function &F = *iter;
      HandleFunction(&F);
    }
    EncryptGVs(M);
    return true;
  } // End runOnModule
};
Pass *createStringEncryptionPass() { return new StringEncryption(); }
} // namespace llvm

char StringEncryption::ID = 0;
static RegisterPass<StringEncryption> X("strenc", "StringEncryption");

这里我们创建了一个ModulePass,顾名思义运行在每个Module之上。LLVM IR的Pass的入口点是对应的 runOnXXX 函数,这里即 runOnModule, 并使用Module的迭代器来遍历所有的函数,并将对应的函数分发给HandleFunction() 方法。 接下来我们开始实现handleFunction函数,这个函数的主要作用是分析函数的相关信息并作处理,也就是所有的重要工作的所在地 。首先我们使用 Function::isDeclaration 来过滤掉所有的declare函数。
然后我们依次遍历函数->基本块->指令->指令的参数:  

set<GlobalVariable *> Globals;
set<Instruction *> Terminators;
for (BasicBlock &BB : *Func) {
      for (Instruction &I : BB) {
        if (ReturnInst *TI = dyn_cast<ReturnInst>(&I)) {
          Terminators.insert(TI);
        }
        for (Value *Op : I.operands()) {
          if (GlobalVariable *G = dyn_cast<GlobalVariable>(Op)) {
            Globals.insert(G);
          }
        }
      }
    }

但,这样的方式并不会收集到我们所用示例中的所有字符串,为什么呢?让我们倒回去看一下中间表示:

%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0))
notail call void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to i8*))

这里对NSLog传递的参数为一个BitCast的常量表达式. LLVM使用的是非常严格的类型系统。比高级编程语言的类型检查更严格,例如,一个装有五个32位整数的数组和一个装有六个32位整数的数组在LLVM的类型体系中是不一样的,对他们的互相替换被视为非法操作。而BitCast指令/常量表达式就是LLVM的强制类型转换指令。在上面的例子中将类型为struct.__NSConstantString_tag指针的全局变量@_unnamed_cfstring_转换成了i8类型的指针,符合NSLog的函数声明。

而printf使用的GEP是LLVM中较为复杂难以理解的一条指令,简单的说GEP的作用是计算地址,详细的解释请参见上面的官方文档和The Often Misunderstood GEP Instruction

无论如何,在增加对应的处理之后我们的代码变成了:

    for (BasicBlock &BB : *Func) {
      for (Instruction &I : BB) {
        if (ReturnInst *TI = dyn_cast<ReturnInst>(&I)) {
          Terminators.insert(TI);
        }
        for (Value *Op : I.operands()) {
          if (GlobalVariable *G = dyn_cast<GlobalVariable>(Op)) {
            Globals.insert(G);
          } else if (Constant *C = dyn_cast<Constant>(Op)) {
            Constant *stripped = C->stripPointerCasts();
            if (GlobalVariable *GV = dyn_cast<GlobalVariable>(stripped)) {
              Globals.insert(GV);
              continue;
            }
          }
        }
      }
    }

接下来我们需要过滤掉不能加密的函数,比如说外部的全局变量,不是正确类型的全局变量,ObjC的元信息,LLVM的元信息等都属于此列。
直接上代码吧没啥好详解的:

if (GV->hasInitializer() &&
          GV->getSection() != StringRef("llvm.metadata") &&
          GV->getSection().find(StringRef("__objc")) == string::npos &&
          GV->getName().find("OBJC") == string::npos) {
        if (isa<ConstantDataSequential>(GV->getInitializer()) || isa<ConstantStruct>(GV->getInitializer())) {
          GV->setConstant(false);
          ConstantDataSequential *CDS =NULL;
          if(isa<ConstantDataSequential>(GV->getInitializer())){
            CDS=dyn_cast<ConstantDataSequential>(GV->getInitializer());
          }
          else if(isa<ConstantStruct>(GV->getInitializer()) && Func->getParent()->getTypeByName("struct.__NSConstantString_tag")!=NULL){
            ConstantStruct* CS=dyn_cast<ConstantStruct>(GV->getInitializer());
            if(CS->getType()!=Func->getParent()->getTypeByName("struct.__NSConstantString_tag")){
              continue;
            }
            GV=cast<GlobalVariable>(CS->getOperand(2)->stripPointerCasts());
            CDS=cast<ConstantDataSequential>(GV->getInitializer());
          }
          else{
            continue;
          }
Type *memberType = CDS->getElementType();
          // Ignore non-IntegerType
          if (!isa<IntegerType>(memberType)) {
            continue;
          }
}

这里我们除了过滤之外,还负责了从struct.__NSConstantString_tag 结构体中提取真实的字符串常量,判断数组所包含的数据类型是不是整数的操作。 接下来我们开始生成对应的解密Key.这里的代码比较屎,欢迎C++大神提点:

if (keymap.find(GV) == keymap.end()) {
            // No Existing Key Found.
            // Perform injection
            if (intType == Type::getInt8Ty(GV->getParent()->getContext())) {
              vector<uint8_t> keys;
              for (unsigned i = 0; i < CDS->getNumElements(); i++) {
                keys.push_back(cryptoutils->get_uint8_t());
              }
              Constant *KeyConst = ConstantDataVector::get(
                  GV->getParent()->getContext(), ArrayRef<uint8_t>(keys));
              keymap[GV] = KeyConst;
            } else if (intType ==
                       Type::getInt16Ty(GV->getParent()->getContext())) {
              vector<uint16_t> keys;
              for (unsigned i = 0; i < CDS->getNumElements(); i++) {
                keys.push_back(cryptoutils->get_uint16_t());
              }
              Constant *KeyConst = ConstantDataVector::get(
                  GV->getParent()->getContext(), ArrayRef<uint16_t>(keys));
              keymap[GV] = KeyConst;
            } else if (intType ==
                       Type::getInt32Ty(GV->getParent()->getContext())) {
              vector<uint32_t> keys;
              for (unsigned i = 0; i < CDS->getNumElements(); i++) {
                keys.push_back(cryptoutils->get_uint32_t());
              }
              Constant *KeyConst = ConstantDataVector::get(
                  GV->getParent()->getContext(), ArrayRef<uint32_t>(keys));
              keymap[GV] = KeyConst;
            } else if (intType ==
                       Type::getInt64Ty(GV->getParent()->getContext())) {
              vector<uint64_t> keys;
              for (unsigned i = 0; i < CDS->getNumElements(); i++) {
                keys.push_back(cryptoutils->get_uint64_t());
              }
              Constant *KeyConst = ConstantDataVector::get(
                  GV->getParent()->getContext(), ArrayRef<uint64_t>(keys));
              keymap[GV] = KeyConst;
            } else {
              errs() << "Unsupported CDS Type\n";
              abort();
            }
          }

这样,和Armariris不同的是,我们为每一项都生成了一组对应的Key. 接下来我们在函数的第一个基本块(EntryBlock)寻找适合插入指令的没有Phi Node等杂项的位置。(实际上函数的EntryBlock不能也不会有PhiNode,具体意思我会在末尾补充)
使用 IRBuilder<> IRB(Func->getEntryBlock().getFirstNonPHIOrDbgOrLifetime ()); 创建IRBuilder, IRBuilder是LLVM提供的方便指令插入的助手模版类。
我们首先创造一个GEP来获得原始变量的指针,然后将其从原来的[数量 x 单个字符大小]BitCast成我们需要的类型。最后加载,完成异或操作后写回原始变量。在Terminator处的处理同理。 注意这是一个Hack并且只能在MinSizeRelease下使用才不会触发Assert。
BinaryOperator按照规矩是只接受Vector的,而clang前端生成的是Array。Again,稳定的实现请参照Hikari的源码

          Value *zero = ConstantInt::get(
              Type::getInt32Ty(GV->getParent()->getContext()), 0);//因为我们从头开始加密。所以gep的索引都是0
          Value *zeroes[] = {zero,zero};
          Value *GEP = IRB.CreateInBoundsGEP(GV, zeroes);
          //BinaryOperations don't take CDAs,only CDVs
          //FIXME: Figure out if CDA and CDV has same mem layout
          Value* BCI=IRB.CreateBitCast(GEP,keymap[GV]->getType()->getPointerTo());
          LoadInst *LI = IRB.CreateLoad(BCI);//ArrayType
          Value *XOR = IRB.CreateXor(LI, keymap[GV]);
          IRB.CreateStore(XOR, BCI);
          for (Instruction *I : Terminators) {
            IRBuilder<> IRB(I);
            Value *zero = ConstantInt::get(
                Type::getInt32Ty(GV->getParent()->getContext()), 0);
            Value *zeroes[] = {zero, zero};
            Value *GEP = IRB.CreateInBoundsGEP(GV, zeroes);
            Value* BCI=IRB.CreateBitCast(GEP,keymap[GV]->getType()->getPointerTo());
            LoadInst *LI = IRB.CreateLoad(BCI);//ArrayType
            Value *XOR = IRB.CreateXor(LI, keymap[GV]);
            IRB.CreateStore(XOR,BCI);
          }

最后,我们在完成后调用我们的EncryptGV。 我们遍历之前创建的映射表。对于unicode类型的字符串编译器默认会放在 __TEXT这个不可写的段,导致我们的XOR触发操作系统保护异常,这需要我们进行修复:   

  void EncryptGVs(Module &M){
    // We've done Instruction Insertation
    // Perform GV Encrytion
    for (map<GlobalVariable *, Constant *>::iterator it = keymap.begin();
         it != keymap.end(); ++it) {
      GlobalVariable *GV = it->first;
      assert(GV->hasInitializer() && "Encrypted GV doesn't have initializer");
      ConstantDataSequential *Key = cast<ConstantDataSequential>(it->second);
      ConstantDataSequential *GVInitializer =
          cast<ConstantDataSequential>(GV->getInitializer());
      assert(Key->getNumElements() == GVInitializer->getNumElements() &&
             "Key and String size mismatch!");
      assert(Key->getElementType() == GVInitializer->getElementType() &&
                    "Key and String type mismatch!");
      Type *memberType = Key->getElementType();
      IntegerType *intType = cast<IntegerType>(memberType);
      //Fixup GV sections otherwise we might fall into __TEXT and get a EXC_i386_GPFLT
      //or other platform's equivalent
      if(GV->getSection().find("__TEXT")!=string::npos){
        GV->setSection("__DATA,__const");
      }

      if (intType == Type::getInt8Ty(M.getContext())) {
        vector<uint8_t> Encrypted;
        for (unsigned i = 0; i < Key->getNumElements(); i++) {
          uint64_t K = Key->getElementAsInteger(i);
          uint64_t S = GVInitializer->getElementAsInteger(i);
          Encrypted.push_back(K^S);
        }
        Constant* newInit=ConstantDataArray::get(M.getContext(),ArrayRef<uint8_t>(Encrypted));
        GV->setInitializer(newInit);
      }
      else if (intType == Type::getInt16Ty(M.getContext())) {
        vector<uint16_t> Encrypted;
        for (unsigned i = 0; i < Key->getNumElements(); i++) {
          uint64_t K = Key->getElementAsInteger(i);
          uint64_t S = GVInitializer->getElementAsInteger(i);
          Encrypted.push_back(K ^ S);
        }
        Constant* newInit=ConstantDataArray::get(M.getContext(),ArrayRef<uint16_t>(Encrypted));
        GV->setInitializer(newInit);
      } else if (intType == Type::getInt32Ty(M.getContext())) {
        vector<uint32_t> Encrypted;
        for (unsigned i = 0; i < Key->getNumElements(); i++) {
          uint64_t K = Key->getElementAsInteger(i);
          uint64_t S = GVInitializer->getElementAsInteger(i);
          Encrypted.push_back(K ^ S);
        }
        Constant* newInit=ConstantDataArray::get(M.getContext(),ArrayRef<uint32_t>(Encrypted));
        GV->setInitializer(newInit);
      } else if (intType == Type::getInt64Ty(M.getContext())) {
        vector<uint64_t> Encrypted;
        for (unsigned i = 0; i < Key->getNumElements(); i++) {
          uint64_t K = Key->getElementAsInteger(i);
          uint64_t S = GVInitializer->getElementAsInteger(i);
          Encrypted.push_back(K ^ S);
        }
        Constant* newInit=ConstantDataArray::get(M.getContext(),ArrayRef<uint64_t>(Encrypted));
        GV->setInitializer(newInit);

      } else {
        errs() << "Unsupported CDS Type\n"<<*intType<<"\n";
        abort();
      }
      errs()<<"Rewritten GlobalVariable:"<<*GVInitializer<<" To:"<<*(GV->getInitializer())<<"\n";
    }
  }

收尾

  • PhiNode指的是一个代表的数值随着控制流的变化而变化的值。例如PhiNode允许当控制流从基本块A跳转时代表1,基本块b跳转时代表2.
  • 我们这里的实现实际上非常简陋,例如当一个全局变量引用另一个文本全局变量时我们没有处理会导致编译失败。这部分需要单独处理并在llvm.global_ctors 中解密,类似于Theos的 %ctor或者__attribute__((constructor))  
  • 这实际上同样不是最好的实现方式。 对于在堆上保存着使用的情况。这种实现返回时会导致字符串被加密回去。

Demo

源文件腾磁盘空间的时候删了。上个当时的截图吧 http://7xibfi.com1.z0.glb.clouddn.com.cfporn.com/uploads/default/original/2X/2/2f1e2d00cca8ee2c51ca05717c2598c36856a747.JPG


免费评分

参与人数 27吾爱币 +29 热心值 +26 收起 理由
ddtsatan + 1 + 1 热心回复!
fungus + 1 谢谢@Thanks!
两桶泡面 + 1 热心回复!
cyril2017 + 1 + 1 用心讨论,共获提升!
xyuetao + 1 + 1 谢谢@Thanks!
zjc841104 + 1 + 1 热心回复!
z17v2ui + 1 + 1 喜欢这种零基础的教程
sunnylds7 + 1 + 1 热心回复!
W丶零度 + 1 + 1 我很赞同!
七情哥哥 + 1 用心讨论,共获提升!
a5606495 + 1 + 1 热心回复!
cjhm + 1 + 1 感谢张总的分享!!!
Nicklobin + 1 + 1 张总威武,开了眼界,之前一直很懵逼。
kbvsfm + 1 + 1 谢谢@Thanks!
pk8900 + 1 + 1 一个没接触过的领域,感谢楼主分享。
wang754782072 + 1 + 1 谢谢@Thanks!
cr7890 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
羽月莉音 + 1 + 1 谢谢@Thanks!
dibh10 + 1 + 1 用心讨论,共获提升!
初亦泽 + 3 + 1 谢谢你
jixun66 + 3 + 1 感谢作者,希望有更多 LLVM 相关内容。
Vsir + 1 + 1 谢谢@Thanks!
孤骜 + 1 + 1 谢谢@Thanks!
wmsuper + 1 + 1 用心讨论,共获提升!
很快再相见123 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Ravey + 1 + 1 谢谢@Thanks!
sushangyu + 1 + 1 虽然什么都看都不懂,但是感觉高大尚

查看全部评分

本帖被以下淘专辑推荐:

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

推荐
发表于 2018-4-10 13:32 | 只看该作者
        谢谢老师无私的奉献

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

推荐
发表于 2018-4-10 09:34 | 只看该作者

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

板凳
发表于 2018-4-9 15:51 | 只看该作者

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

报纸
发表于 2018-4-9 16:01 | 只看该作者
支持张总

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

地板
发表于 2018-4-9 16:18 | 只看该作者
好像很厉害,但是没看懂

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

7#
发表于 2018-4-9 17:15 | 只看该作者
谢谢楼主的分享

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

8#
发表于 2018-4-9 17:47 | 只看该作者
感谢分享.

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

9#
发表于 2018-4-9 19:07 | 只看该作者
很精彩,认真学习了。感谢分享

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

10#
发表于 2018-4-9 20:38 | 只看该作者
认真学习

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

11#
发表于 2018-4-10 00:11 | 只看该作者
谢谢楼主分享,希望继续更新

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

12#
发表于 2018-4-10 00:42 | 只看该作者
感谢楼主的分享,很精彩,认真学习了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则


免责声明:
吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Service@52PoJie.Cn

快速回复 收藏帖子 返回列表 搜索

吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2018-4-19 13:38

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表
早龙早餐加盟 早点加盟培训 早餐加盟项目 天津早点加盟有哪些 天津早点加盟车
早餐行业加盟 加盟早点车 北京早点摊加盟 雄州早餐怎么加盟 豆浆早餐加盟
品牌早餐加盟 早点来早餐加盟 早点加盟好项目 小投资加盟店 湖南特色早点加盟
春光早餐加盟 早餐面馆加盟 安徽早餐加盟 早点加盟好项目 四川特色早点加盟
百度