一种基于LLVM IR的字符串变形方法

第一种方法是将字符串转换成对应的整型数组

namespace
{
    struct Str2Array : public ModulePass
    {
        static char ID;  // Pass identification, replacement for typeid

        Str2Array() : ModulePass(ID)
        {
            func__Enc_dec = NULL;
            llvm_memcpy_p0i8_p0i8_i32 = NULL;
            IsWChar = false;
        }

        // run - 
        bool runOnModule(Module &M) override;
        void print(raw_ostream &O, const Module* = nullptr) const override { }
        bool IsCString(GlobalVariable* GV);
        bool IsASCString(GlobalVariable* GV);
        bool IsUnicodeString(GlobalVariable* GV);
        // getAnalysisUsage - This pass requires the CallGraph.
        void getAnalysisUsage(AnalysisUsage &AU) const override {}
        void ProcessGVStringSubstitute(GlobalVariable* GV);
        void RemoveOrigGVString();
    protected:
        Function*  func__Enc_dec;
        Function* llvm_memcpy_p0i8_p0i8_i32;
        bool IsWChar;
        vector<GlobalVariable*> DeleteGlobalVar;
    };
}

void Str2Array::RemoveOrigGVString()
{
    int nSize = DeleteGlobalVar.size();
    for (int i = 0; i < nSize; i++)
        if(DeleteGlobalVar[i]->getNumUses() == 0)
            DeleteGlobalVar[i]->eraseFromParent();
}

//替换字符串
void Str2Array::ProcessGVStringSubstitute(GlobalVariable* GV)
{
    if (ConstantDataSequential * CDS = dyn_cast<ConstantDataSequential>(GV->getInitializer()))
    {

        GV->dump(); // 打印出来,看看结果
        StringRef RawData = CDS->getRawDataValues();
        int EltNum; 
        EltNum = CDS->getNumElements();
        int length; 
        if(IsWChar)
            length = EltNum * sizeof(WORD);
        else
            length = EltNum * sizeof(BYTE);
        int NewArraySize = length / 4;
        int offset = length % 4;
        if (offset) NewArraySize++;
        ArrayType* NewArrayTy = ArrayType::get(IntegerType::get(GV->getContext(), 32), NewArraySize);
        vector<unsigned int> NewArrayValue;
        int i = 0;
        const char* p = RawData.data();
        for (i = 0; i < NewArraySize;i++)
        {
            unsigned int tmp = *(unsigned int*)(&p[4 * i]);
            NewArrayValue.push_back(tmp);
        }
        NewArrayValue[i - 1] &= ((1 << offset * 8) - 1);

        while (!GV->use_empty())
        {
            User* tmpUser = GV->user_back();
            if (Instruction* TargetInst = dyn_cast<Instruction>(tmpUser)) //在这条指令前插入我们的开辟堆栈和赋值的语句
            {
                if(TargetInst->getOpcode() != Instruction::GetElementPtr)
                {
                    errs() << "This TargetInst is not a GetElementPtr Inst" << "\n";
                    continue;
                }
                AllocaInst* AllocArray = new AllocaInst(NewArrayTy, "New Array", TargetInst);
                for (i = 0; i < NewArraySize; i++)
                {
                    ConstantInt* const_int0 = ConstantInt::get(GV->getContext(), APInt(32, StringRef("0"), 10));
                    ConstantInt* const_int_i = ConstantInt::get(IntegerType::getInt32Ty(GV->getContext()), i);
                    ConstantInt* const_ArrayValue = ConstantInt::get(IntegerType::getInt32Ty(GV->getContext()), NewArrayValue[i]);
                    GetElementPtrInst* ptr_arrayidx = GetElementPtrInst::Create(NewArrayTy, AllocArray, { const_int0,const_int_i }, "arrayidx_" + Twine(i), TargetInst);
                    StoreInst* store2stack = new StoreInst(const_ArrayValue, ptr_arrayidx, false, TargetInst);
                }
                CastInst* Cast2int8_16ptr = nullptr;
                if(IsWChar)
                    //Cast2int8_16ptr = new BitCastInst(AllocArray, PointerType::get(IntegerType::getInt16Ty(GV->getContext()), 0), "cast2WChar*", TargetInst);
                    Cast2int8_16ptr = new BitCastInst(AllocArray, GV->getType(), "cast2WChar*", TargetInst);
                else
                    //Cast2int8_16ptr = new BitCastInst(AllocArray, PointerType::get(IntegerType::getInt8Ty(GV->getContext()), 0), "cast2Char*", TargetInst);
                    Cast2int8_16ptr = new BitCastInst(AllocArray, GV->getType(), "cast2Char*", TargetInst);
                TargetInst->replaceUsesOfWith(GV, Cast2int8_16ptr);
            }
            else if(ConstantExpr* CExpr = dyn_cast<ConstantExpr>(tmpUser))
            {
                if(CExpr->getOpcode() != Instruction::GetElementPtr)
                {
                    errs() << "The Constant is not a GetElementPtr" << "\n";
                    CExpr->dump();
                    continue;
                }
                while (!CExpr->user_empty())
                {
                    User* CExpUser = CExpr->user_back();
                    if (Instruction* inst = dyn_cast<Instruction>(CExpUser))
                    {
                        AllocaInst* AllocArray = new AllocaInst(NewArrayTy, "New Array", inst);
                        for (i = 0; i < NewArraySize; i++)
                        {
                            ConstantInt* const_int0 = ConstantInt::get(GV->getContext(), APInt(32, StringRef("0"), 10));
                            ConstantInt* const_int_i = ConstantInt::get(IntegerType::getInt32Ty(GV->getContext()), i);
                            ConstantInt* const_ArrayValue = ConstantInt::get(IntegerType::getInt32Ty(GV->getContext()), NewArrayValue[i]);
                            GetElementPtrInst* ptr_arrayidx = GetElementPtrInst::Create(NewArrayTy, AllocArray, { const_int0,const_int_i }, "arrayidx_" + Twine(i), inst);
                            StoreInst* store2stack = new StoreInst(const_ArrayValue, ptr_arrayidx, false, inst);
                        }
                        CastInst* Cast2int8_16ptr = nullptr;
                        if (IsWChar)
                            Cast2int8_16ptr = new BitCastInst(AllocArray, GV->getType(), "cast2WChar*", inst);
                        else
                            Cast2int8_16ptr = new BitCastInst(AllocArray, GV->getType(), "cast2Char*", inst);

                        vector<Value*> ptr_index_struct;
                        ArrayRef<Value*> tmpArrayRef = makeArrayRef(ptr_index_struct);
                        for (int j = 1;j < CExpr->getNumOperands();j++)
                        {
                            ptr_index_struct.push_back(CExpr->getOperand(j));
                        }
                        tmpArrayRef = makeArrayRef(ptr_index_struct);

                        //验证类型
                        GV->getValueType()->dump();
                        cast<PointerType>(Cast2int8_16ptr->getType()->getScalarType())->getElementType()->dump();
                        GetElementPtrInst* GetNewAddr = GetElementPtrInst::Create(GV->getValueType(), Cast2int8_16ptr, tmpArrayRef, "Fake_constatnExpr", inst);
                        inst->replaceUsesOfWith(CExpr, GetNewAddr);
                    }
                    else
                    {
                        errs() << "The CExprUser is not a Inst" << "\n";
                        errs() << *CExpUser << "\n";
                    }
                }
                //替换完所有的常量表达式后,删除此常量
                if(CExpr->getNumUses() == 0)
                    CExpr->destroyConstant();
            }
            else
            {
                errs() << "This User is not a Inst or ConstantExpr"<< "\n";
                errs() << *tmpUser<< "\n";
            }
        }
    }
    if (GV->use_empty())
    {
        DeleteGlobalVar.push_back(GV);  //先保存起来,处理后再删除
    } 
    else
    {
        errs() << "there are still some users using the GV " << *GV << "\n";
        for (Value::user_iterator useri = GV->user_begin(), usere = GV->user_end(); useri != usere; useri++)
        {
            useri->dump();
        }
    }
}

bool Str2Array::IsCString(GlobalVariable* GV)
{
    if(IsASCString(GV))
    {
        IsWChar = false;
        return true;
    }
    else if (IsUnicodeString(GV))
    {
        IsWChar = true;
        return true;
    }
    return false;
}

bool Str2Array::IsASCString(GlobalVariable* GV)
{
    if(GV->hasDefinitiveInitializer())
    {
        if(ConstantDataSequential * CDS = dyn_cast<ConstantDataSequential>(GV->getInitializer()))
        {
            if (CDS->isCString()) return true;
        }
    }
    return false;
}

bool Str2Array::IsUnicodeString(GlobalVariable* GV)
{
    if(GV->hasDefinitiveInitializer())
    {
        if(ConstantDataSequential* CDS = dyn_cast<ConstantDataSequential>(GV->getInitializer()))
        {
            if(CDS->getElementType() == IntegerType::getInt16Ty(GV->getContext()))
            {
                StringRef RawData = CDS->getRawDataValues();
                int EltNum = CDS->getNumElements();
                int length = EltNum * sizeof(WORD);
                //errs() << RawData << "\n"; //这个在测试时输出的是宽字符的apple
                if (RawData[length - 1] == 0 && RawData[length - 2] == 0)//简易的判断是否为Unicode字符串
                {
                    for (int i = 0; i < length - 2 - 1;i++)
                    {
                        if (RawData[i] == 0 && RawData[i + 1] == 0) return false;
                    }
                    //如果字符串内只有最后的两个元素为0x00,那么基本可以判定它是一个unicode字符串
                    return true;
                }
            }
        }
    }
    return false;
}
bool Str2Array::runOnModule(Module &M)
{
    Module* mod = &M;
    //遍历全局变量,找字符串类型的
    for (Module::global_iterator gi = mod->global_begin();gi != mod->global_end();gi++)
    {
        GlobalVariable* g_value = (GlobalVariable*)gi;
        //只处理本地全局变量和局部变量  static 和 private 、linkOnceODR
        //增加LinkOnceODR这种类型,此类型出现比较多,一般都是用在字符串复制上
        if (!(g_value->hasLocalLinkage() || g_value->hasLinkOnceODRLinkage()))
        {
            continue;
        }
        if (IsCString(g_value))
        {
            ProcessGVStringSubstitute(g_value);
        }
    }
    RemoveOrigGVString();
    return true;
}

char Str2Array::ID = 0;
static RegisterPass<Str2Array> X("str2array", "change string to char array");
Pass* llvm::createStr2Array()
{
    return new Str2Array();
};

Pass* llvm::createStr2Array(bool flag)
{
    if (flag != false) return  new Str2Array();
    return nullptr;
};

测试源码为

#include <stdio.h>
int global_a = 11;
int global_b = 13;

int sub(int a, int b);
int sum(int a, int b);

int   main()
{
    int a;
    int b;

    int choice;
    printf("pls input your choice, 1 for add, 2 for sub, 0 for end \n");
    while (1)
    {
        scanf_s("%d", &choice);
        switch (choice)
        {
        case 0:
            goto end;
        case 1:
        {
                  a = sum(global_a, global_b);
                  printf("global_a + global_b =%d\n", a);
                  break;
        }
        case 2:
        {
                  b = sub(global_a, global_b);
                  printf("global_a - global_b =%d\n", b);
                  break;
        }
        default:printf("no correct choice,pls input the right one\n"); break;
        }

    }
end:    
    printf("----the end------");
    return 0;

}

int sub(int a, int b)
{
    return a - b;
}

int sum(int a, int b)
{
    return a + b;
}

编译成中间文件(ll)

@"\01?global_a@@3HA" = global i32 11, align 4
@"\01?global_b@@3HA" = global i32 13, align 4
@"\01??_C@_0DJ@FGCLOFBN@pls?5input?5your?5choice?0?51?5for?5add@" = linkonce_odr unnamed_addr constant [57 x i8] c"pls input your choice, 1 for add, 2 for sub, 0 for end \0A\00", comdat, align 1
@"\01??_C@_02DPKJAMEF@?$CFd?$AA@" = linkonce_odr unnamed_addr constant [3 x i8] c"%d\00", comdat, align 1
@"\01??_C@_0BJ@BEHJBLCA@global_a?5?$CL?5global_b?5?$DN?$CFd?6?$AA@" = linkonce_odr unnamed_addr constant [25 x i8] c"global_a + global_b =%d\0A\00", comdat, align 1
@"\01??_C@_0BJ@EHOIHCME@global_a?5?9?5global_b?5?$DN?$CFd?6?$AA@" = linkonce_odr unnamed_addr constant [25 x i8] c"global_a - global_b =%d\0A\00", comdat, align 1
@"\01??_C@_0CL@EEHIEKFJ@no?5correct?5choice?0pls?5input?5the?5@" = linkonce_odr unnamed_addr constant [43 x i8] c"no correct choice,pls input the right one\0A\00", comdat, align 1
@"\01??_C@_0BC@GINEGEGI@?9?9?9?9the?5end?9?9?9?9?9?9?$AA@" = linkonce_odr unnamed_addr constant [18 x i8] c"----the end------\00", comdat, align 1

; Function Attrs: norecurse nounwind
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  %a = alloca i32, align 4
  %b = alloca i32, align 4
  %choice = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"\01??_C@_0DJ@FGCLOFBN@pls?5input?5your?5choice?0?51?5for?5add@", i32 0, i32 0))
  br label %while.body

while.body:                                       ; preds = %entry, %sw.epilog
  %call1 = call i32 (i8*, ...) @scanf_s(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"\01??_C@_02DPKJAMEF@?$CFd?$AA@", i32 0, i32 0), i32* %choice)
  %0 = load i32, i32* %choice, align 4
  switch i32 %0, label %sw.default [
    i32 0, label %sw.bb
    i32 1, label %sw.bb2
    i32 2, label %sw.bb5
  ]

sw.bb:                                            ; preds = %while.body
  br label %end

sw.bb2:                                           ; preds = %while.body
  %1 = load i32, i32* @"\01?global_b@@3HA", align 4
  %2 = load i32, i32* @"\01?global_a@@3HA", align 4
  %call3 = call i32 @"\01?sum@@YAHHH@Z"(i32 %2, i32 %1)
  store i32 %call3, i32* %a, align 4
  %3 = load i32, i32* %a, align 4
  %call4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @"\01??_C@_0BJ@BEHJBLCA@global_a?5?$CL?5global_b?5?$DN?$CFd?6?$AA@", i32 0, i32 0), i32 %3)
  br label %sw.epilog

sw.bb5:                                           ; preds = %while.body
  %4 = load i32, i32* @"\01?global_b@@3HA", align 4
  %5 = load i32, i32* @"\01?global_a@@3HA", align 4
  %call6 = call i32 @"\01?sub@@YAHHH@Z"(i32 %5, i32 %4)
  store i32 %call6, i32* %b, align 4
  %6 = load i32, i32* %b, align 4
  %call7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @"\01??_C@_0BJ@EHOIHCME@global_a?5?9?5global_b?5?$DN?$CFd?6?$AA@", i32 0, i32 0), i32 %6)
  br label %sw.epilog

sw.default:                                       ; preds = %while.body
  %call8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"\01??_C@_0CL@EEHIEKFJ@no?5correct?5choice?0pls?5input?5the?5@", i32 0, i32 0))
  br label %sw.epilog

sw.epilog:                                        ; preds = %sw.default, %sw.bb5, %sw.bb2
  br label %while.body

end:                                              ; preds = %sw.bb
  %call9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"\01??_C@_0BC@GINEGEGI@?9?9?9?9the?5end?9?9?9?9?9?9?$AA@", i32 0, i32 0))
  ret i32 0
}

经过转换后的中间文件为

; ModuleID = 'sumsub.ll'
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc18.0.0"

@"\01?global_a@@3HA" = global i32 11, align 4
@"\01?global_b@@3HA" = global i32 13, align 4

; Function Attrs: norecurse nounwind
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  %a = alloca i32, align 4
  %b = alloca i32, align 4
  %choice = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  %"New Array" = alloca [15 x i32]
  %arrayidx_0 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 0
  store i32 544435312, i32* %arrayidx_0
  %arrayidx_1 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 1
  store i32 1970302569, i32* %arrayidx_1
  %arrayidx_2 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 2
  store i32 1870209140, i32* %arrayidx_2
  %arrayidx_3 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 3
  store i32 1663070837, i32* %arrayidx_3
  %arrayidx_4 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 4
  store i32 1667854184, i32* %arrayidx_4
  %arrayidx_5 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 5
  store i32 824192101, i32* %arrayidx_5
  %arrayidx_6 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 6
  store i32 1919903264, i32* %arrayidx_6
  %arrayidx_7 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 7
  store i32 1684300064, i32* %arrayidx_7
  %arrayidx_8 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 8
  store i32 540155948, i32* %arrayidx_8
  %arrayidx_9 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 9
  store i32 544370534, i32* %arrayidx_9
  %arrayidx_10 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 10
  store i32 744650099, i32* %arrayidx_10
  %arrayidx_11 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 11
  store i32 1713385504, i32* %arrayidx_11
  %arrayidx_12 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 12
  store i32 1696625263, i32* %arrayidx_12
  %arrayidx_13 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 13
  store i32 169895022, i32* %arrayidx_13
  %arrayidx_14 = getelementptr [15 x i32], [15 x i32]* %"New Array", i32 0, i32 14
  store i32 0, i32* %arrayidx_14
  %"cast2Char*" = bitcast [15 x i32]* %"New Array" to [57 x i8]*
  %Fake_constatnExpr = getelementptr [57 x i8], [57 x i8]* %"cast2Char*", i32 0, i32 0
  %call = call i32 (i8*, ...) @printf(i8* %Fake_constatnExpr)
  br label %while.body

while.body:                                       ; preds = %sw.epilog, %entry
  %"New Array1" = alloca [1 x i32]
  %arrayidx_02 = getelementptr [1 x i32], [1 x i32]* %"New Array1", i32 0, i32 0
  store i32 25637, i32* %arrayidx_02
  %"cast2Char*3" = bitcast [1 x i32]* %"New Array1" to [3 x i8]*
  %Fake_constatnExpr4 = getelementptr [3 x i8], [3 x i8]* %"cast2Char*3", i32 0, i32 0
  %call1 = call i32 (i8*, ...) @scanf_s(i8* %Fake_constatnExpr4, i32* %choice)
  %0 = load i32, i32* %choice, align 4
  switch i32 %0, label %sw.default [
    i32 0, label %sw.bb
    i32 1, label %sw.bb2
    i32 2, label %sw.bb5
  ]

sw.bb:                                            ; preds = %while.body
  br label %end

sw.bb2:                                           ; preds = %while.body
  %1 = load i32, i32* @"\01?global_b@@3HA", align 4
  %2 = load i32, i32* @"\01?global_a@@3HA", align 4
  %call3 = call i32 @"\01?sum@@YAHHH@Z"(i32 %2, i32 %1)
  store i32 %call3, i32* %a, align 4
  %3 = load i32, i32* %a, align 4
  %"New Array5" = alloca [7 x i32]
  %arrayidx_06 = getelementptr [7 x i32], [7 x i32]* %"New Array5", i32 0, i32 0
  store i32 1651469415, i32* %arrayidx_06
  %arrayidx_17 = getelementptr [7 x i32], [7 x i32]* %"New Array5", i32 0, i32 1
  store i32 1633643617, i32* %arrayidx_17
  %arrayidx_28 = getelementptr [7 x i32], [7 x i32]* %"New Array5", i32 0, i32 2
  store i32 1730161440, i32* %arrayidx_28
  %arrayidx_39 = getelementptr [7 x i32], [7 x i32]* %"New Array5", i32 0, i32 3
  store i32 1633841004, i32* %arrayidx_39
  %arrayidx_410 = getelementptr [7 x i32], [7 x i32]* %"New Array5", i32 0, i32 4
  store i32 543317868, i32* %arrayidx_410
  %arrayidx_511 = getelementptr [7 x i32], [7 x i32]* %"New Array5", i32 0, i32 5
  store i32 174335293, i32* %arrayidx_511
  %arrayidx_612 = getelementptr [7 x i32], [7 x i32]* %"New Array5", i32 0, i32 6
  store i32 0, i32* %arrayidx_612
  %"cast2Char*13" = bitcast [7 x i32]* %"New Array5" to [25 x i8]*
  %Fake_constatnExpr14 = getelementptr [25 x i8], [25 x i8]* %"cast2Char*13", i32 0, i32 0
  %call4 = call i32 (i8*, ...) @printf(i8* %Fake_constatnExpr14, i32 %3)
  br label %sw.epilog

sw.bb5:                                           ; preds = %while.body
  %4 = load i32, i32* @"\01?global_b@@3HA", align 4
  %5 = load i32, i32* @"\01?global_a@@3HA", align 4
  %call6 = call i32 @"\01?sub@@YAHHH@Z"(i32 %5, i32 %4)
  store i32 %call6, i32* %b, align 4
  %6 = load i32, i32* %b, align 4
  %"New Array15" = alloca [7 x i32]
  %arrayidx_016 = getelementptr [7 x i32], [7 x i32]* %"New Array15", i32 0, i32 0
  store i32 1651469415, i32* %arrayidx_016
  %arrayidx_117 = getelementptr [7 x i32], [7 x i32]* %"New Array15", i32 0, i32 1
  store i32 1633643617, i32* %arrayidx_117
  %arrayidx_218 = getelementptr [7 x i32], [7 x i32]* %"New Array15", i32 0, i32 2
  store i32 1730161952, i32* %arrayidx_218
  %arrayidx_319 = getelementptr [7 x i32], [7 x i32]* %"New Array15", i32 0, i32 3
  store i32 1633841004, i32* %arrayidx_319
  %arrayidx_420 = getelementptr [7 x i32], [7 x i32]* %"New Array15", i32 0, i32 4
  store i32 543317868, i32* %arrayidx_420
  %arrayidx_521 = getelementptr [7 x i32], [7 x i32]* %"New Array15", i32 0, i32 5
  store i32 174335293, i32* %arrayidx_521
  %arrayidx_622 = getelementptr [7 x i32], [7 x i32]* %"New Array15", i32 0, i32 6
  store i32 0, i32* %arrayidx_622
  %"cast2Char*23" = bitcast [7 x i32]* %"New Array15" to [25 x i8]*
  %Fake_constatnExpr24 = getelementptr [25 x i8], [25 x i8]* %"cast2Char*23", i32 0, i32 0
  %call7 = call i32 (i8*, ...) @printf(i8* %Fake_constatnExpr24, i32 %6)
  br label %sw.epilog

sw.default:                                       ; preds = %while.body
  %"New Array25" = alloca [11 x i32]
  %arrayidx_026 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 0
  store i32 1663070062, i32* %arrayidx_026
  %arrayidx_127 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 1
  store i32 1701999215, i32* %arrayidx_127
  %arrayidx_228 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 2
  store i32 1663071331, i32* %arrayidx_228
  %arrayidx_329 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 3
  store i32 1667854184, i32* %arrayidx_329
  %arrayidx_430 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 4
  store i32 1819290725, i32* %arrayidx_430
  %arrayidx_531 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 5
  store i32 1852383347, i32* %arrayidx_531
  %arrayidx_632 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 6
  store i32 544503152, i32* %arrayidx_632
  %arrayidx_733 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 7
  store i32 543516788, i32* %arrayidx_733
  %arrayidx_834 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 8
  store i32 1751607666, i32* %arrayidx_834
  %arrayidx_935 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 9
  store i32 1852776564, i32* %arrayidx_935
  %arrayidx_1036 = getelementptr [11 x i32], [11 x i32]* %"New Array25", i32 0, i32 10
  store i32 2661, i32* %arrayidx_1036
  %"cast2Char*37" = bitcast [11 x i32]* %"New Array25" to [43 x i8]*
  %Fake_constatnExpr38 = getelementptr [43 x i8], [43 x i8]* %"cast2Char*37", i32 0, i32 0
  %call8 = call i32 (i8*, ...) @printf(i8* %Fake_constatnExpr38)
  br label %sw.epilog

sw.epilog:                                        ; preds = %sw.default, %sw.bb5, %sw.bb2
  br label %while.body

end:                                              ; preds = %sw.bb
  %"New Array39" = alloca [5 x i32]
  %arrayidx_040 = getelementptr [5 x i32], [5 x i32]* %"New Array39", i32 0, i32 0
  store i32 757935405, i32* %arrayidx_040
  %arrayidx_141 = getelementptr [5 x i32], [5 x i32]* %"New Array39", i32 0, i32 1
  store i32 543516788, i32* %arrayidx_141
  %arrayidx_242 = getelementptr [5 x i32], [5 x i32]* %"New Array39", i32 0, i32 2
  store i32 761556581, i32* %arrayidx_242
  %arrayidx_343 = getelementptr [5 x i32], [5 x i32]* %"New Array39", i32 0, i32 3
  store i32 757935405, i32* %arrayidx_343
  %arrayidx_444 = getelementptr [5 x i32], [5 x i32]* %"New Array39", i32 0, i32 4
  store i32 45, i32* %arrayidx_444
  %"cast2Char*45" = bitcast [5 x i32]* %"New Array39" to [18 x i8]*
  %Fake_constatnExpr46 = getelementptr [18 x i8], [18 x i8]* %"cast2Char*45", i32 0, i32 0
  %call9 = call i32 (i8*, ...) @printf(i8* %Fake_constatnExpr46)
  ret i32 0
}

消除了程序中的字符串变量,在最终生成的exe中也不包含任何字符串数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值