├── raid2019-zhang-li.pdf ├── rex ├── execfunction ├── misuseprofile ├── bin2vex.py ├── problock.py └── bin2ir3.py ├── README.md └── idascript └── bin2iridc.idc /raid2019-zhang-li.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglikernel/CRYPTOREX/HEAD/raid2019-zhang-li.pdf -------------------------------------------------------------------------------- /rex/execfunction: -------------------------------------------------------------------------------- 1 | void *memset(void *s, int ch, size_t n) dest:1:string src:2:int len:3:int 2 | void *memcpy(void *dest, const void *src, size_t n) dest:1:string src:2:string len:3:int 3 | char *strcpy(char* dest, const char *src) dest:1:string src:2:string 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CryptoREX: Large-scale Analysis of Cryptographic Misuse in IoT Devices 2 | CryptoREX is a firmware analysis tool to detect crypto misuses in IoT devices. Now it supports multiple architetures, including ARM, MIPS, MIPSel, etc. 3 | # Prerequisites 4 | 1. IDA Pro. We tested version 6.4. 5 | 2. Python. We tested version 2.7.4. 6 | 3. angr 7 | 4. buildroot 8 | # How to use 9 | python bin2vex.py (input_dir) (middle_dir) (middle_dir) (output_dir) (output_dir) 10 | # How to cite 11 | Li Zhang, Jiongyi Chen, [Wenrui Diao](https://diaowenrui.github.io/), [Shanqing Guo](http://faculty.sdu.edu.cn/guoshanqing/zh_CN/), [Jian Weng](https://xxxy2016.jnu.edu.cn/Item/1534.aspx), and [Kehuan Zhang](https://staff.ie.cuhk.edu.hk/~khzhang/). [CryptoREX: Large-scale Analysis of Cryptographic Misuse in IoT Devices.](https://github.com/zhanglikernel/CRYPTOREX/blob/master/raid2019-zhang-li.pdf) The 22nd International Symposium on Research in Attacks, Intrusions and Defenses (RAID), Beijing, China. September, 2019. 12 | # Paper Abstract 13 | Cryptographic functions play a critical role in the secure transmission and storage of application data. Although most crypto functions are well-defined and carefully-implemented in standard libraries, in practice, they could be easily misused or incorrectly encapsulated due to its error-prone nature and inexperience of developers. This situation is even worse in the IoT domain, given that developers tend to sacrifice security for performance in order to suit resource-constrained IoT devices. Given the severity and the pervasiveness of such bad practice, it is crucial to raise public awareness about this issue, find the misuses and shed light on best practices. 14 | 15 | In this paper, we design and implement CryptoREX, a framework to identify crypto misuse of IoT devices under diverse architectures and in a scalable manner. In particular, CryptoREX lifts binary code to a unified IR and performs static taint analysis across multiple executables. To aggressively capture and identify misuses of self-defined crypto APIs, CryptoREX dynamically updates the API list during taint analysis and automatically tracks the function arguments. Running on 521 firmware images with 165 pre-defined crypto APIs, it successfully discovered 679 crypto misuse issues in total, which on average costs only 1120 seconds per firmware. Our study shows 24.2% of firmware images violate at least one misuse rule, and most of the discovered misuses are unknown before. The misuses could result in sensitive data leakage, authentication bypass, password brute-force, etc. Our findings highlight the poor implementation and weak protection in today's IoT development 16 | -------------------------------------------------------------------------------- /idascript/bin2iridc.idc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | static listfunction(filename){ 5 | auto str; 6 | auto ea; 7 | auto begin; 8 | auto end; 9 | ea = 0x0; 10 | auto wfd = fopen(filename,"a"); 11 | fprintf(wfd,"all function:\n"); 12 | while(ea != BADADDR){ 13 | str = GetFunctionName(ea); 14 | if(str == 0 || strstr(SegName(ea),"extern") != -1 || strstr(SegName(ea),"plt") != -1 || strstr(SegName(ea),"stubs") != -1){ 15 | ea = NextFunction(ea); 16 | continue; 17 | } 18 | //auto dl = GetType(ea); 19 | //fprintf(wfd,"0x%X\t%s %s",ea,str,dl); 20 | fprintf(wfd,"0x%X\t%s",ea,str); 21 | begin = ea; 22 | end = FindFuncEnd(ea); 23 | while(begin < end){ 24 | begin = FindText(begin,SEARCH_DOWN,10,0,"sp"); 25 | if(begin == -1){ 26 | break; 27 | } 28 | if(strstr(GetMnem(begin),"add") != -1 || strstr(GetMnem(begin),"ADD") != -1 || strstr(GetMnem(begin),"sub") != -1 || strstr(GetMnem(begin),"SUB") != -1 || strstr(GetMnem(begin),"STM") != -1 || strstr(GetMnem(begin),"MOV") != -1 || strstr(GetMnem(begin),"mov") != -1){ 29 | if(GetOpnd(begin,0) == "SP" || GetOpnd(begin,0) == "sp" || GetOpnd(begin,0) == "$sp" || GetOpnd(begin,0) == "$SP" || GetOpnd(begin,0) == "SP!" ){ 30 | fprintf(wfd,":0x%X",begin); 31 | break; 32 | } 33 | } 34 | begin = begin + ItemSize(begin); 35 | } 36 | fprintf(wfd,"\n"); 37 | ea = NextFunction(ea); 38 | } 39 | fclose(wfd); 40 | } 41 | 42 | static calltofunction(filename){ 43 | auto str,end,begin; 44 | auto ea; 45 | ea = 0x0; 46 | auto wfd = fopen(filename,"a"); 47 | fprintf(wfd,"lcom\n"); 48 | while(ea != BADADDR){ 49 | str = GetFunctionName(ea); 50 | begin = ea; 51 | if(str != 0 && SegName(ea) != "extern" && SegName(ea) != ".plt" && strstr(SegName(ea),"stubs") == -1){ 52 | end = FindFuncEnd(ea); 53 | fprintf(wfd,"-----------------\n0x%X 0x%x %s \n",ea,end,str); 54 | } 55 | while(begin < end){ 56 | auto dl = GetDisasm(begin); 57 | auto s = strstr(dl,";"); 58 | auto lcom = substr(dl,s+1,strlen(dl)); 59 | while(strstr(lcom," ") != -1){ 60 | lcom = substr(lcom,strstr(lcom," ")+1,strlen(lcom)); 61 | } 62 | if(s != -1){ 63 | fprintf(wfd,"0x%X ;%s\n",begin,lcom); 64 | begin =begin+ ItemSize(begin); 65 | continue; 66 | } 67 | dl = GetDisasm(begin); 68 | s = strstr(dl,"#"); 69 | lcom = substr(dl,s+1,strlen(dl)); 70 | while(strstr(lcom," ") != -1){ 71 | lcom = substr(lcom,strstr(lcom," ")+1,strlen(lcom)); 72 | } 73 | if(s != -1){ 74 | fprintf(wfd,"0x%X #%s\n",begin,lcom); 75 | begin =begin+ ItemSize(begin); 76 | continue; 77 | } 78 | begin =begin+ ItemSize(begin); 79 | } 80 | ea = NextFunction(ea); 81 | } 82 | fclose(wfd); 83 | } 84 | 85 | static printfname(filename){ 86 | auto sourcefile; 87 | auto wfd; 88 | sourcefile = GetInputFilePath(); 89 | wfd = fopen(filename,"w"); 90 | fprintf(wfd,"%s\n",sourcefile); 91 | fclose(wfd); 92 | } 93 | 94 | static getpltfunctiontype(filename){ 95 | auto wfd,ea,str; 96 | auto segend; 97 | auto segbegin; 98 | auto dl; 99 | auto ft; 100 | wfd = fopen(filename,"a"); 101 | fprintf(wfd,"pltfunctiontype\n"); 102 | ea = 0x0; 103 | while(ea != BADADDR ){ 104 | str = GetFunctionName(ea); 105 | if(str != 0 && (SegName(ea) == ".plt" || strstr(SegName(ea),"stubs") != -1)){ 106 | ft = trim(GetType(ea)); 107 | fprintf(wfd,"0x%X\t%s\t%s\n",ea,str,ft); 108 | } 109 | ea = NextFunction(ea); 110 | } 111 | ea = FirstSeg(); 112 | while(ea != BADADDR){ 113 | if(strstr(SegName(ea),"got") != -1 || strstr(SegName(ea),"extern" ) != -1){ 114 | segend = SegEnd(ea); 115 | segbegin = ea; 116 | while(segbegin < segend){ 117 | dl = GetDisasm(segbegin); 118 | if(strstr(dl,".word") != -1){ 119 | dl = ltoa(Dword(segbegin),16); 120 | } 121 | if(strstr(dl,".extern") != -1){ 122 | dl = substr(dl,strstr(dl,".extern") + 7 , strlen(dl)); 123 | } 124 | if(strstr(dl,".got") != -1){ 125 | dl = substr(dl,strstr(dl,".got") + 4 , strlen(dl)); 126 | } 127 | ft = GetType(segbegin); 128 | fprintf(wfd,"0x%X\t%s\t%s\n",segbegin,dl,ft); 129 | segbegin = segbegin + ItemSize(segbegin); 130 | } 131 | } 132 | ea = NextSeg(ea); 133 | } 134 | fclose(wfd); 135 | } 136 | 137 | static listdata(segname,filename){ 138 | auto selector; 139 | auto segea; 140 | auto segend; 141 | auto itemend; 142 | auto wfd; 143 | wfd = fopen(filename,"a"); 144 | selector = SegByName(segname); 145 | segea = SegByBase(selector); 146 | segend = SegEnd(segea); 147 | fprintf(wfd,"%s\n",segname); 148 | while(segea < segend){ 149 | auto dl = GetDisasm(segea); 150 | if(strstr(dl,"ALIGN") == 0){ 151 | segea = segea + ItemSize(segea); 152 | continue; 153 | } 154 | fprintf(wfd,"0x%X\t%s\n",segea,dl); 155 | segea = segea + ItemSize(segea); 156 | } 157 | fclose(wfd); 158 | } 159 | 160 | static getalldata(filename){ 161 | listdata(".rodata",filename); 162 | listdata(".data",filename); 163 | } 164 | 165 | 166 | static getfunctiondata(filename){ 167 | auto functionbegin; 168 | auto functionend; 169 | auto str; 170 | auto begin, end; 171 | auto wfd; 172 | wfd = fopen(filename,"a"); 173 | functionbegin = 0x0; 174 | functionbegin = NextFunction(functionbegin); 175 | 176 | fprintf(wfd,"functionenddata\n"); 177 | while(functionbegin != BADADDR){ 178 | str = GetFunctionName(functionbegin); 179 | if( str == 0 || SegName(functionbegin) != ".text"){ 180 | functionbegin = NextFunction(functionbegin); 181 | continue; 182 | } 183 | functionend = FindFuncEnd(functionbegin); 184 | functionbegin = NextFunction(functionbegin); 185 | begin = functionend; 186 | end = functionbegin; 187 | while(begin < end){ 188 | auto dl = GetDisasm(begin); 189 | if(strstr(dl,"DC") != 0){ 190 | begin = begin + ItemSize(begin); 191 | continue; 192 | } 193 | if(Dfirst(begin) != -1){ 194 | fprintf(wfd,"0x%X\t%d\n",begin,Dfirst(begin)); 195 | }else{ 196 | fprintf(wfd,"0x%X\t%s\n",begin,dl); 197 | } 198 | begin = begin + ItemSize(begin); 199 | } 200 | } 201 | fclose(wfd); 202 | } 203 | 204 | 205 | static main() 206 | { 207 | if(ARGV.count < 2){ 208 | Exit(-1); 209 | } 210 | auto filename; 211 | filename = ARGV[1]; 212 | printfname(filename); 213 | listfunction(filename); 214 | calltofunction(filename); 215 | getpltfunctiontype(filename); 216 | getalldata(filename); 217 | getfunctiondata(filename); 218 | Exit(0); 219 | } 220 | -------------------------------------------------------------------------------- /rex/misuseprofile: -------------------------------------------------------------------------------- 1 | ruledes: 2 | 1 constants salt 3 | 2 constants keys 4 | 3 constants iv 5 | 4 using ecb mode 6 | 5 using static seed for rand 7 | 6 iteration 8 | misusefunction: 9 | #int DES_processFile(a,b,c,ps) 4:string:2: 10 | #cryptlib 11 | int cryptImportKey( const void *encryptedKey, const int encryptedKeyLength, const CRYPT_CONTEXT importContext, const CRYPT_CONTEXT sessionKeyContext) 4:string:2:;1:none:3: 12 | int cryptSetAttribute( const CRYPT_HANDLE cryptObject, const CRYPT_ATTRIBUTE_TYPE attributeType, const int value) 3:int:4:4 13 | #GnuTLS 14 | #libgcrypt 15 | gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *hd, int algo, int mode, unsigned int flags) 3:int:4:=1 16 | gcry_error_t gcry_cipher_setiv(gcry_cipher_hd_t h, const void *k, size_t l) 2:string:3: 17 | gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t h, const void *k, size_t l) 2:string:2: 18 | #libcrypto 19 | int AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key) 1:string:2: 20 | int AES_set_decrypt_key (const unsigned char *userKey, const int bits, AES_KEY *key) 1:string:2: 21 | void AES_ecb_encrypt (const unsigned char *in, unsigned char *out, const AES_KEY *key, const int enc) 1:none:4: 22 | void AES_cbc_encrypt (const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc) 5:string:3: 23 | void AES_cfb128_encrypt (const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc) 5:string:3: 24 | void AES_cfb1_encrypt (const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc) 5:string:3: 25 | void AES_cfb8_encrypt (const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc) 5:string:3: 26 | void AES_ofb128_encrypt (const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, int *num) 5:string:3: 27 | int AES_wrap_key (AES_KEY *key, const unsigned char *iv, unsigned char *out, const unsigned char *in, unsigned int inlen) 2:string:3: 28 | int AES_unwrap_key (AES_KEY *key, const unsigned char *iv, unsigned char *out, const unsigned char *in, unsigned int inlen) 2:string:3: 29 | void BF_set_key(BF_KEY *key, int len, const unsigned char *data) 3:string:2: 30 | void AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) 1:none:4: 31 | void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) 1:none:4: 32 | void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,BF_KEY *key, int enc); 1:none:4: 33 | void BF_cbc_encrypt(const unsigned char *in, unsigned char *out,long length, BF_KEY *schedule, unsigned char *ivec, int enc) 5:string:3: 34 | void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,long length, BF_KEY *schedule, unsigned char *ivec, int *num,int enc) 5:string:3: 35 | void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,long length, BF_KEY *schedule, unsigned char *ivec, int *num) 5:string:3: 36 | void BF_encrypt(BF_LONG *data,const BF_KEY *key) 1:none:4: 37 | void BF_decrypt(BF_LONG *data,const BF_KEY *key) 1:none:4: 38 | int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key) 1:string:2: 39 | void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key, const int enc) 1:none:4: 40 | void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, const int enc) 5:string:3: 41 | void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) 5:string:3: 42 | void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) 5:string:3: 43 | void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) 5:string:3: 44 | void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num) 5:string:3: 45 | void Camellia_encrypt (const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) 1:none:4: 46 | void Camellia_decrypt (const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) 1:none:4: 47 | void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) 1:string:2: 48 | void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key, int enc) 1:none:4: 49 | void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key) 1:none:4: 50 | void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key) 1:none:4: 51 | void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, const CAST_KEY *ks, unsigned char *iv, int enc) 5:string:3: 52 | void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length, const CAST_KEY *schedule, unsigned char *ivec, int *num, int enc) 5:string:3: 53 | void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length, const CAST_KEY *schedule, unsigned char *ivec, int *num) 5:string:3: 54 | void DES_ecb2_encrypt(const_DES_cblock *input, DES_cblock *output,DES_key_schedule *ks1, DES_key_schedule *ks2, int enc) 1:none:4: 55 | void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, int enc) 1:none:4: 56 | void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output,long length, DES_key_schedule *schedule, DES_cblock *ivec,int enc) 5:string:3: 57 | void DES_cfb_encrypt(const unsigned char *in, unsigned char *out,int numbits, long length, DES_key_schedule *schedule,DES_cblock *ivec, int enc) 6:string:3: 58 | void DES_ofb_encrypt(const unsigned char *in, unsigned char *out,int numbits, long length, DES_key_schedule *schedule,DES_cblock *ivec) 6:string:3: 59 | void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,long length, DES_key_schedule *schedule, DES_cblock *ivec,int enc) 5:string:3: 60 | void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,long length, DES_key_schedule *schedule, DES_cblock *ivec,int *num, int enc) 4:string:3: 61 | void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out,long length, DES_key_schedule *schedule, DES_cblock *ivec,int *num) 4:string:3: 62 | void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, long length, DES_key_schedule *schedule, DES_cblock *ivec, const_DES_cblock *inw, const_DES_cblock *outw, int enc) 5:string:3: 63 | void DES_ede2_cbc_encrypt(const unsigned char *input, unsigned char *output, long length, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_cblock *ivec, int enc) 6:string:3: 64 | void DES_ede2_cfb64_encrypt(const unsigned char *in,unsigned char *out, long length, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_cblock *ivec, int *num, int enc) 6:string:3: 65 | void DES_ede2_ofb64_encrypt(const unsigned char *in,unsigned char *out, long length, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_cblock *ivec, int *num) 6:string:3: 66 | void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, long length, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec,int enc) 7:string:3: 67 | void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,long length, DES_key_schedule *ks1, DES_key_schedule *ks2,DES_key_schedule *ks3, DES_cblock *ivec, int *num, int enc) 7:string:3: 68 | void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out,long length, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_key_schedule *ks3,DES_cblock *ivec, int *num) 7:string:3: 69 | void DES_string_to_2keys(const char *str, DES_cblock *key1,DES_cblock *key2) 1:string:2: 70 | void DES_string_to_key(const char *str, DES_cblock *key) 1:string:2: 71 | void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,DES_key_schedule *ks, int enc) 0:none:4: 72 | char *DES_fcrypt(const char *buf, const char *salt, char *ret) 2:string:1: 73 | char *DES_crypt(const char *buf, const char *salt) 2:string:1: 74 | void RC2_set_key (RC2_KEY *key, int len, const unsigned char *data, int bits) 3:string:2: 75 | void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *key, int enc) 1:none:4: 76 | void RC2_encrypt(unsigned long *data, RC2_KEY *key) 1:none:4: 77 | void RC2_decrypt(unsigned long *data, RC2_KEY *key) 1:none:4: 78 | void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, RC2_KEY *ks, unsigned char *iv, int enc) 5:string:3: 79 | void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length, RC2_KEY *schedule, unsigned char *ivec, int *num, int enc) 5:string:3: 80 | void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length, RC2_KEY *schedule, unsigned char *ivec, int *num) 5:string:3: 81 | void EVP_aes_128_ecb(int) 1:none:4: 82 | void EVP_aes_192_ecb(int) 1:none:4: 83 | void EVP_aes_256_ecb(int) 1:none:4: 84 | void EVP_bf_ecb(int) 1:none:4: 85 | void EVP_camellia_128_ecb(int) 1:none:4: 86 | void EVP_camellia_192_ecb(int) 1:none:4: 87 | void EVP_camellia_256_ecb(int) 1:none:4: 88 | void EVP_cast5_ecb(int) 1:none:4: 89 | void EVP_des_ecb(int) 1:none:4: 90 | void EVP_des_ede3_ecb(int) 1:none:4: 91 | void EVP_des_ede3_ecb(int) 1:none:4: 92 | int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char *key, unsigned char *iv, int enc) 3:string:2:;4:string:3: 93 | int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char *key, unsigned char *iv) 3:string:2:;4:string:3: 94 | int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char *key, unsigned char *iv) 3:string:2:;4:string:3: 95 | int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, unsigned char *key, unsigned char *iv, int enc) 4:string:2:;5:string:3: 96 | int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, unsigned char *key, unsigned char *iv) 4:string:2:;5:string:3: 97 | int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, unsigned char *key, unsigned char *iv) 4:string:2:;5:string:3: 98 | int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,const unsigned char *salt, const unsigned char *data, int datal, int count, unsigned char *key,unsigned char *iv) 3:string:1:;4:string:2:;6:int:6:<1000; 99 | #libsodium 100 | #Nettle 101 | #openssl 102 | #libtomcrypt 103 | #libk5crypto 104 | #libbcmcrypto 105 | #libcrypt 106 | char *crypt(const char *key, const char *salt) 1:string:2:;2:string:1: 107 | #int rand() ::; 108 | #wolfcrypt 109 | int wc_AesSetKey(Aes *aes, const byte *key, word32 len, const byte *iv, int dir) 2:string:2:;4:string:3: 110 | int wc_AesSetIV(Aes *aes, const byte *iv) 2:string:3: 111 | void wc_AesEncryptDirect(Aes *aes, byte *out, const byte *in) 1:none:4: 112 | void wc_AesDecryptDirect(Aes *aes, byte *out, const byte *in) 1:none:4: 113 | int wc_AesSetKeyDirect (Aes *aes, const byte *key, word32 len, const byte *iv, int dir) 2:string:2:;4:string:3: 114 | int wc_AesGcmSetKey (Aes *aes, const byte *key, word32 len) 2:string:2: 115 | int wc_CamelliaSetKey (Camellia *cam, const byte *key, word32 len, const byte *iv) 2:string:2:;4:string:3: 116 | int wc_CamelliaSetIV (Camellia *cam, const byte *iv) 2:string:3: 117 | int wc_CamelliaEncryptDirect (Camellia *cam, byte *out, const byte *in) 1:none:4: 118 | int wc_CamelliaDecryptDirect (Camellia *cam, byte *out, const byte *in) 1:none:4: 119 | int wc_Des_SetKey (Des *des, const byte *key, const byte *iv, int dir) 2:string:2:;3:string:3: 120 | void wc_Des_SetIV (Des *des, const byte *iv) 2:string:3: 121 | int wc_Des_EcbEncrypt (Des *des, byte *out, const byte *in, word32 sz) 1:none:3: 122 | int wc_Des3_EcbEncrypt (Des3 *des, byte *out, const byte *in, word32 sz) 1:none:3: 123 | int wc_Des3_SetKey (Des3 *des, const byte *key, const byte *iv, int dir) 2:string:2:;3:string:3: 124 | int wc_Des3_SetIV (Des3 *des, const byte *iv) 2:string:3: 125 | int wc_Des_CbcDecryptWithKey (byte *out, const byte *in, word32 sz, const byte *key, const byte *iv) 4:string:2:;5:string:3: 126 | int wc_Des_CbcEncryptWithKey (byte *out, const byte *in, word32 sz, const byte *key, const byte *iv) 4:string:2:;5:string:3: 127 | int wc_Des3_CbcEncryptWithKey (byte *out, const byte *in, word32 sz, const byte *key, const byte *iv) 4:string:2:;5:string:3: 128 | int wc_Des3_CbcDecryptWithKey (byte *out, const byte *in, word32 sz, const byte *key, const byte *iv) 4:string:2:;5:string:3: 129 | #int strcmp(const char *a ,const char *b) 1:string:1: 130 | void srand(int seed) 1:int:5: 131 | -------------------------------------------------------------------------------- /rex/bin2vex.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import pyvex 3 | import subprocess 4 | import StringIO 5 | import string 6 | 7 | import sys 8 | import os 9 | import pwd 10 | 11 | import gzip 12 | import zipfile 13 | import tarfile 14 | import rarfile 15 | 16 | import magic 17 | import binwalk 18 | import shutil 19 | 20 | import commands 21 | 22 | from bin2ir3 import idarun 23 | from bin2ir3 import transbin2IR 24 | 25 | from enum import Enum 26 | import copy 27 | import re 28 | import time 29 | 30 | #statistical information 31 | numdecompress = 0 32 | numfirmware = 0 33 | numextracted = 0 34 | 35 | allruleresult = dict(); 36 | soset = dict(); 37 | execset = dict(); 38 | name2path = dict(); 39 | ousingrandset = dict(); 40 | 41 | cryptlibset = {"libcrypto", "libcrypt", "libssl", "libgcrypt", "libwolfssl", "libmcrypt"}; 42 | 43 | class randtype(Enum): 44 | Orand = 1; 45 | Osrand = 2; 46 | Orsrand = 3; 47 | Nrand = 4; 48 | 49 | class compressmethod(Enum): 50 | Egz = 0; 51 | Etar = 1; 52 | Etgz = 2; 53 | Ezip = 3; 54 | Erar = 4; 55 | Edir = -2; 56 | Eunknown = -1; 57 | 58 | def getcompressmethod(filename): 59 | result = compressmethod.Eunknown; 60 | if os.path.isdir(filename): 61 | result = compressmethod.Edir; 62 | return result 63 | filetype = _get_filetype(filename); 64 | if filetype == "application/gzip": 65 | result = compressmethod.Egz; 66 | elif filetype == "application/x-tar": 67 | result = compressmethod.Etar; 68 | elif filetype == "application/zip": 69 | result = compressmethod.Ezip; 70 | elif filetype == "application/x-rar": 71 | result = compressmethod.Erar; 72 | return result; 73 | 74 | 75 | def filenameformat(filename): 76 | filename = filename.replace("(","\\("); 77 | filename = filename.replace(")","\\)"); 78 | return filename; 79 | 80 | 81 | def _get_filetype(data,mime=True): 82 | return magic.from_file(data,mime); 83 | 84 | def un_gz(filename,outputpath): 85 | g_file = gzip.GzipFile(filename); 86 | dirname = path2filename(filename); 87 | open(outputpath +"/" + dirname , "w+").write(g_file.read()); 88 | g_file.close(); 89 | return outputpath +"/" + dirname; 90 | 91 | def un_tar(filename,outputpath): 92 | tar = tarfile.open(filename); 93 | names = tar.getnames(); 94 | dirname = path2filename(filename); 95 | if os.path.isdir(outputpath+"/" + dirname): 96 | pass; 97 | else: 98 | os.mkdir(outputpath+"/"+dirname); 99 | for name in names: 100 | tar.extract(name,outputpath + "/" + dirname +"/"); 101 | tar.close(); 102 | return outputpath+"/" + dirname; 103 | 104 | 105 | 106 | def un_zip(file_name,outputpath): 107 | zip_file = zipfile.ZipFile(file_name); 108 | dirname = path2filename(file_name); 109 | if os.path.isdir(outputpath+"/" + dirname): 110 | pass; 111 | else: 112 | os.mkdir(outputpath+"/" + dirname); 113 | for names in zip_file.namelist(): 114 | print(names); 115 | try: 116 | zip_file.extract(names,outputpath+"/" + dirname+ "/"); 117 | except BadZipfile as err: 118 | print(err); 119 | print(outputpath+"/" + dirname); 120 | #finally: 121 | #print("return"); 122 | #return; 123 | zip_file.close(); 124 | return outputpath+"/" + dirname; 125 | 126 | def un_rar(filename,outputpath): 127 | rar = rarfile.RarFile(filename); 128 | dirname = path2filename(filename); 129 | if os.path.isdir(outputpath + "/" + dirname): 130 | pass; 131 | else: 132 | os.mkdir(outputpath + "/" + dirname); 133 | pwd = os.getcwd(); 134 | os.chdir(outputpath + "/" + dirname); 135 | rar.extractall(); 136 | rar.close(); 137 | os.chdir(pwd); 138 | return outputpath + "/" + dirname; 139 | 140 | 141 | def decompress(file_name,outputdir,dc = True): 142 | filetype = getcompressmethod(file_name); 143 | #print(file_name) 144 | global numdecompress; 145 | if filetype == compressmethod.Ezip: 146 | try: 147 | if dc: 148 | numdecompress += 1; 149 | un_zip(file_name,outputdir); 150 | except BaseException as err: 151 | print(file_name); 152 | elif filetype == compressmethod.Erar: 153 | try: 154 | un_rar(file_name,outputdir); 155 | if dc: 156 | numdecompress += 1; 157 | except BaseException as err: 158 | print(file_name); 159 | elif filetype == compressmethod.Egz: 160 | tmpresult = un_gz(file_name,outputdir); 161 | if dc: 162 | numdecompress += 1; 163 | filetype2 = getcompressmethod(tmpresult); 164 | if not filetype2 == compressmethod.Eunknown: 165 | decompress(tmpresult,outputdir,dc = False); 166 | os.remove(tmpresult); 167 | elif filetype == compressmethod.Etar: 168 | un_tar(file_name,outputdir); 169 | if dc: 170 | numdecompress += 1; 171 | elif filetype == compressmethod.Etgz: 172 | pass; 173 | elif filetype == compressmethod.Eunknown: 174 | shutil.copyfile(file_name, outputdir + getfilenamefrompath(file_name)); 175 | pass; 176 | return True; 177 | 178 | def nmfile(sofile): 179 | result = set(); 180 | sofile =filenameformat(sofile); 181 | filetype = _get_filetype(filename); 182 | if not filetype == b"application/x-sharedlib": 183 | return result; 184 | output = os.popen("nm -D " + sofile); 185 | allline = output.read().split("\n"); 186 | for line in allline: 187 | field = line.split(" "); 188 | if not len(field) == 3 or not field[1] == "T": 189 | continue; 190 | result.add(field[2]); 191 | return result; 192 | 193 | 194 | def extractfile(filename,outputdir): 195 | filetype = _get_filetype(filename); 196 | if any(s in [filetype] for s in [b"application/x-executable", 197 | b"application/x-dosexec", 198 | b"application/x-object", 199 | b"application/pdf", 200 | b"application/msword", 201 | b"image/", b"text/", b"video/"]): 202 | return; 203 | filetype = _get_filetype(filename,mime=False); 204 | if any(s in [filetype] for s in [b"executable", b"universal binary", 205 | b"relocatable", b"bytecode", b"applet"]): 206 | return; 207 | print(filename); 208 | pwd = os.getcwd(); 209 | os.chdir(outputdir); 210 | global numfirmware; 211 | numfirmware += 1; 212 | for module in binwalk.scan(filename,"-r","-e" ,"-y", "filesystem", signature=True, quiet=True, extract=True): 213 | print ("%s Results:" % module.name) 214 | for result in module.results: 215 | if module.extractor.output.has_key(result.file.path): 216 | if module.extractor.output[result.file.path].extracted.has_key(result.offset): 217 | print ("Extracted '%s' at offset 0x%X from '%s' to '%s'" % (result.description.split(',')[0],result.offset,result.file.path,str(module.extractor.output[result.file.path].extracted[result.offset]))) 218 | os.chdir(pwd); 219 | return True; 220 | 221 | 222 | def getfilenamefrompath(path): 223 | return path[path.rindex("/") + 1:len(path)]; 224 | 225 | class archtype(Enum): 226 | Elarm = 0; 227 | Elmips = 1; 228 | Eunknown = -1; 229 | 230 | def libformat(libname,filetype): 231 | result = ""; 232 | if not filetype == b"application/x-sharedlib": 233 | return result; 234 | lindex = 0; 235 | if not libname.find("/") == -1: 236 | lindex = libname.rindex("/")+1; 237 | if not libname.find(".so") == -1: 238 | result = libname[lindex:libname.find(".so")].strip(); 239 | elif not libname.find(".a") == -1: 240 | result = libname[lindex:libname.find(".a")].strip(); 241 | else: 242 | result = libname[lindex:len(libname)]; 243 | return result; 244 | 245 | 246 | def listallso(filename,arch): 247 | soset = set(); 248 | commandstr = ""; 249 | if arch == archtype.Elmips: 250 | commandstr = "$HOME/buildroot/output/host/bin/ldd" 251 | elif arch == archtype.Elarm: 252 | commandstr = "$HOME/armbuildroot/output/host/bin/ldd" 253 | else: 254 | return soset; 255 | filename = filenameformat(filename); 256 | (status,output) = commands.getstatusoutput( commandstr + ' ' + filename); 257 | #print(output); 258 | #print(filename); 259 | #print(filename); 260 | outstr = output.splitlines(); 261 | for line in outstr: 262 | if "=>" in line: 263 | soname = line.split("=>")[0]; 264 | #print(soname); 265 | if not soname.find(".so") == -1: 266 | soname = soname[:soname.find(".so")].strip(); 267 | elif not soname.find(".a") == -1: 268 | soname = soname[:soname.find(".a")].strip(); 269 | soset.add(soname); 270 | return soset; 271 | 272 | def _getarch(filename): 273 | result = archtype.Eunknown; 274 | filetype = ""; 275 | filename = filenameformat(filename); 276 | filetype = _get_filetype(filename); 277 | if not any(s in [filetype] for s in [b"application/x-executable",b"application/x-sharedlib"]): 278 | return result; 279 | (status,output) = commands.getstatusoutput('readelf -h ' + filename); 280 | outstr = output.splitlines(); 281 | if not len(outstr) > 9: 282 | return result; 283 | fields=outstr[8].split(); 284 | if not len(fields) > 1: 285 | return result; 286 | if fields[1] == "ARM": 287 | result = archtype.Elarm; 288 | elif fields[1] == "MIPS": 289 | result = archtype.Elmips; 290 | return result; 291 | 292 | def isusecrypt(filename,arch): 293 | filename = filenameformat(filename); 294 | result = False; 295 | if arch == archtype.Elarm: 296 | (status,output) = commands.getstatusoutput('armobjdump.sh ' + filename + " | grep -E -i \"gcry|EVP|CAST|SSL|encry|cry|aes|DES|decry\""); 297 | if(len(output) > 0): 298 | outstr = output.splitlines(); 299 | outputline = filename; 300 | for line in outstr: 301 | allfield = line.split(); 302 | if(len(allfield) == 2): 303 | outputline += " " + allfield[1][0:len(allfield[1])-1]; 304 | print(outputline); 305 | result = True; 306 | elif arch == archtype.Elmips: 307 | (status,output) = commands.getstatusoutput('mipsobjdump.sh ' + filename + " | grep -E -i \"gcry|EVP|CAST|SSL|encry|cry|aes|DES|decry\""); 308 | if(len(output) > 0): 309 | outstr = output.splitlines(); 310 | outputline = filename; 311 | for line in outstr: 312 | allfield = line.split(); 313 | if(len(allfield) == 2): 314 | outputline += " " + allfield[1][0:len(allfield[1])-1]; 315 | print(outputline); 316 | result = True; 317 | else: 318 | pass; 319 | return result; 320 | 321 | def filterfile(filename,outputdir): 322 | arch = _getarch(filename); 323 | #print(filename); 324 | #soset = listallso(filename,arch); 325 | #if len(soset) == 0: 326 | # return; 327 | '''for so in soset: 328 | 329 | if "libgcry" in so or "libcry" in so or "libssl" in so or "libgcry" in so: 330 | shutil.copyfile(filename, outputdir + getfilenamefrompath(filename)); 331 | #print(filename); 332 | break; 333 | #print(so);''' 334 | #print(filename); 335 | if isusecrypt(filename,arch): 336 | shutil.copyfile(filename, outputdir + getfilenamefrompath(filename)); 337 | return True; 338 | 339 | 340 | def translateIR(filename,outputdir,importfc = dict()): 341 | '''print(filename); 342 | filetype = _get_filetype(filename); 343 | filename = filenameformat(filename); 344 | outputdir = filenameformat(outputdir); 345 | onlyfilename = getfilenamefrompath(filename); 346 | #option = 0; 347 | if onlyfilename == "busybox": 348 | return; 349 | if not any(s in [filetype] for s in [b"application/x-executable", 350 | b"application/x-object",b"application/x-sharedlib"]): 351 | #print(filename); 352 | return; 353 | if filetype == b"application/x-executable": 354 | option = 0; 355 | elif filetype == b"application/x-sharedlib": 356 | option = 1; 357 | elif filetype == b"application/x-object": 358 | option = 1; 359 | if filename.endswith(".ko"): 360 | option = 2; 361 | outputfile = outputdir + "/" + onlyfilename+"ir"; 362 | print("python angrir.py " + filename + " " + outputfile + " > " + outputfile); 363 | os.system("python angrir.py " + filename + " " + outputfile + " > " + outputfile) 364 | return;''' 365 | onlyfilename = getfilenamefrompath(filename); 366 | outputfile = outputdir + "/" + onlyfilename; 367 | return transbin2IR(filename,outputfile,importfc); 368 | 369 | def getIRtmp(filename,outputdir): 370 | arch = _getarch(filename); 371 | #print(filename); 372 | #soset = listallso(filename,arch); 373 | #print(soset); 374 | filetype = _get_filetype(filename); 375 | filename = filenameformat(filename); 376 | outputdir = filenameformat(outputdir); 377 | onlyfilename = getfilenamefrompath(filename); 378 | if onlyfilename == "busybox": 379 | return; 380 | if not any(s in [filetype] for s in [b"application/x-executable", 381 | b"application/x-object",b"application/x-sharedlib"]): 382 | return; 383 | outputdir += onlyfilename; 384 | idarun(filename,outputdir); 385 | return True; 386 | 387 | 388 | 389 | def challown(filename): 390 | filename = filenameformat(filename); 391 | os.ystem("chown $USER:$USER " + filename); 392 | 393 | 394 | def mkdir(path): 395 | if not os.path.exists(path): 396 | os.makedirs(path); 397 | 398 | def getfileowner(filename): 399 | filename = filenameformat(filename); 400 | (status,output) = commands.getstatusoutput('ls -al ' + filename); 401 | print(filename); 402 | print(output); 403 | result = output.split()[2]; 404 | return result; 405 | 406 | ''' keep dir struct''' 407 | def dfs_dir(path,outputpath,operationf = None,operationd = None): 408 | stack = []; 409 | ret = []; 410 | stack.append(path); 411 | if not outputpath == None: 412 | mkdir(outputpath); 413 | oresult = True; 414 | while len(stack) > 0: 415 | tmp = stack.pop(len(stack) - 1); 416 | #print(tmp); 417 | try: 418 | if(os.path.isdir(tmp)): 419 | print(tmp); 420 | #ret.append(tmp); 421 | Doutputpath = tmp[tmp.index(path)+len(path):tmp.rindex("/")]; 422 | destpath = ""; 423 | if Doutputpath == "": 424 | destpath = outputpath + "/"; 425 | else: 426 | destpath = outputpath + "/" + Doutputpath + "/"; 427 | if not operationd == None: 428 | oresult = operationd(tmp,destpath); 429 | if not oresult: 430 | continue; 431 | for item in os.listdir(tmp): 432 | fullfilenamestr = os.path.join(tmp,item); 433 | stack.append(fullfilenamestr); 434 | elif(os.path.isfile(tmp)): 435 | #print(tmp); 436 | ret.append(tmp); 437 | Doutputpath = tmp[tmp.index(path)+len(path):tmp.rindex("/")]; 438 | destpath = ""; 439 | if Doutputpath == "": 440 | destpath = outputpath + "/"; 441 | else: 442 | destpath = outputpath + "/" + Doutputpath + "/"; 443 | mkdir(destpath); 444 | if not operationf == None: 445 | operationf(tmp,destpath); 446 | except IOError: 447 | print(tmp); 448 | except OSError: 449 | print(tmp); 450 | return ret; 451 | 452 | def path2filename(path): 453 | fullfilename = path[path.rindex("/")+1:len(path)]; 454 | prefixfilename = fullfilename[0:fullfilename.rindex(".")]; 455 | return prefixfilename; 456 | 457 | def usingrand(fullformatname): 458 | result=randtype.Nrand; 459 | output = os.popen("nm -D " + fullformatname); 460 | regex = re.compile('\s+'); 461 | allline = output.read().split("\n"); 462 | functionset = set(); 463 | for line in allline: 464 | field = regex.split(line); 465 | if not len(field) == 3 or not field[1] == "U": 466 | continue; 467 | functionset.add(field[2].strip()); 468 | if "rand" in functionset and "srand" in functionset: 469 | result = randtype.Orsrand; 470 | elif "rand" in functionset: 471 | result = randtype.Orand; 472 | elif "srand" in functionset: 473 | result = randtype.Osrand; 474 | return result; 475 | 476 | #def rootfinddfs(path,dirname,soset,execset): 477 | def soexecfile(fullname,outputdir): 478 | global soset; 479 | global execset; 480 | global name2path; 481 | fullname = filenameformat(fullname); 482 | filetype = _get_filetype(fullname); 483 | arch = _getarch(fullname); 484 | filename = ""; 485 | if fullname.find("/") == -1: 486 | filename = fullname; 487 | else: 488 | filename = fullname[fullname.rindex("/")+1:len(fullname)] 489 | if filetype == b"application/x-executable": 490 | allso = listallso(fullname,arch); 491 | #print(allso); 492 | for allsoitem in allso: 493 | if not allsoitem in execset: 494 | execset[allsoitem] = set(); 495 | execset[allsoitem].add(filename); 496 | name2path[filename] = fullname; 497 | if usingrand(fullname) == randtype.Orand: 498 | ousingrandset[filename] = fullname; 499 | #execset[allso] = filename; 500 | elif filetype == b"application/x-sharedlib": 501 | filename = libformat(fullname,filetype); 502 | allso = listallso(fullname,arch); 503 | for allsoitem in allso: 504 | if not allsoitem in soset: 505 | soset[allsoitem] = set(); 506 | soset[allsoitem].add(filename); 507 | name2path[filename] = fullname; 508 | if usingrand(fullname) == randtype.Orand: 509 | ousingrandset[filename] = fullname; 510 | #soset[allso] = filename; 511 | return True; 512 | 513 | def wdetail(df,prompt,dinfo=dict()): 514 | wfd = open(df,"a"); 515 | wfd.write(prompt+"\n"); 516 | for item in dinfo: 517 | wfd.write(dinfo[item][0]+"\n"); 518 | wfd.close(); 519 | 520 | def wfsummury(sf,prompt,sdict = dict()): 521 | wfd = open(sf,"a"); 522 | wfd.write(prompt+"\n"); 523 | for item in sdict: 524 | wfd.write(item + " " + str(sdict[item]) + "\n"); 525 | wfd.close(); 526 | 527 | def summurycount(dinfo,result): 528 | for ditemindex in dinfo: 529 | ditem = dinfo[ditemindex]; 530 | print(ditem[1]); 531 | print(ditem[2]); 532 | if not str(ditem[1]) + " " + str(ditem[2]) in result: 533 | result[str(ditem[1]) + " " + str(ditem[2])] = 1; 534 | else: 535 | result[str(ditem[1]) + " " + str(ditem[2])] += 1; 536 | if not str(ditem[1]) + " " + str(ditem[2]) in allruleresult: 537 | allruleresult[str(ditem[1]) + " " + str(ditem[2])] = 1; 538 | else: 539 | allruleresult[str(ditem[1]) + " " + str(ditem[2])] += 1; 540 | 541 | def systemconstruct(dirfullpath,outputdir): 542 | global soset; 543 | global execset; 544 | global cryptlibset; 545 | global name2path; 546 | global ousingrandset; 547 | dirname = "" 548 | result = True; 549 | currentset = cryptlibset; 550 | currentnextset = set(); 551 | allfset = currentset; 552 | alleset = set(); 553 | alldepend=dict(); 554 | summtable=dict(); 555 | writefirst = True; 556 | if dirfullpath.find("/") == -1: 557 | dirname = dirfullpath; 558 | else: 559 | dirname = dirfullpath[dirfullpath.rindex("/") + 1:len(dirfullpath)]; 560 | print(dirname); 561 | if dirname.endswith("extracted"): 562 | testbegintime = time.time(); 563 | transtimesum = 0; 564 | firmname = dirname[0:dirname.find(".extracted")]; 565 | filloutputdir = ""; 566 | if not dirfullpath.find("/") == -1: 567 | filloutputdir = outputdir + "/" + dirfullpath[dirfullpath.rindex("/") + 1:]; 568 | else: 569 | filloutputdir = outputdir; 570 | detailreportfile = filloutputdir + ".dreport" 571 | summuaryreportfile = filloutputdir + ".summary" 572 | global numextracted; 573 | numextracted += 1; 574 | result = False; 575 | soset.clear(); 576 | execset.clear(); 577 | name2path.clear(); 578 | ousingrandset.clear(); 579 | dfs_dir(dirfullpath,outputdir+"/"+dirname,operationf=soexecfile,operationd=None); 580 | #libmap 581 | for currentitem in currentset: 582 | if currentitem in soset: 583 | loadsoset = soset[currentitem]; 584 | currentnextset = currentnextset.union(loadsoset); 585 | while len(currentnextset) > 0: 586 | currentset = copy.copy(currentnextset); 587 | currentnextset.clear(); 588 | print(currentset); 589 | print(allfset); 590 | for currentitem in currentset: 591 | print(currentitem); 592 | if currentitem in allfset or currentitem == "cupsd" or currentitem == "libtorrent-rasterbar" or currentitem == "smbd" or currentitem == "libperl" or currentitem == "libphp5" or currentitem == "libapr-1":# or currentitem == "tdbbackup" or currentitem == "net" or currentitem == "libbigballofmud" or currentitem == "smbpasswd" or currentitem == "libsysctxlua" or currentitem == "libzebra" or currentitem == "libcurl" or currentitem == "ssl" or currentitem == "zebra" or currentitem == "stunnel" or currentitem == "libntpass": 593 | continue; 594 | onlyfilename = getfilenamefrompath(name2path[currentitem]); 595 | if os.path.getsize(name2path[currentitem]) / float(1024*1024) > 10: 596 | continue; 597 | a = time.time(); 598 | getIRtmp(name2path[currentitem],filloutputdir + "/"); 599 | b = time.time(); 600 | print("getIRtmp:%f"%(b-a)); 601 | testbegintime2 = time.time(); 602 | (exporteddic,detailreport) = translateIR(filloutputdir + "/" + onlyfilename + "idcom",filloutputdir); 603 | testendtime2 = time.time(); 604 | transtimesum += (testendtime2 - testbegintime2); 605 | if not len(detailreport) == 0 and writefirst: 606 | writefirst = False; 607 | wdetail(detailreportfile,firmname); 608 | wdetail(detailreportfile,currentitem); 609 | wdetail(detailreportfile,name2path[currentitem],detailreport); 610 | summurycount(detailreport,summtable); 611 | elif not len(detailreport) == 0: 612 | wdetail(detailreportfile,currentitem); 613 | wdetail(detailreportfile,name2path[currentitem],detailreport); 614 | summurycount(detailreport,summtable); 615 | alldepend[currentitem] = exporteddic; 616 | if currentitem in soset: 617 | loadsoset = soset[currentitem]; 618 | currentnextset = currentnextset.union(loadsoset); 619 | allfset = allfset.union(currentset); 620 | for allfitem in allfset: 621 | if allfitem in execset: 622 | alleset = alleset.union(execset[allfitem]); 623 | print("------"); 624 | print(alleset); 625 | for execitem in alleset: 626 | print(execitem); 627 | if execitem == "openssl" or execitem == "ssh" or execitem == "smbd" or execitem == "perl" or execitem.find("php") == 0 or execitem == "mysqld" or execitem == "pppd" or execitem == "vsftpd" or execitem == "busybox" or execitem == "stunnel" or execitem == "zebra" or execitem == "email" or execitem == "sshd" or execitem == "ldapwhoami" or execitem == "mount.cifs":# or execitem == "httpd" or execitem == "dhclient" or execitem == "guardian" or execitem == "jnap" or execitem == "fwupd" or execitem == "curl" or execitem == "sshd" or execitem == "wget":#wgets for 360 628 | continue; 629 | if os.path.getsize(name2path[execitem]) / float(1024*1024) > 10: 630 | continue; 631 | print(execitem); 632 | so = listallso(name2path[execitem],_getarch(name2path[execitem])); 633 | importedso = dict(); 634 | for soitem in so: 635 | if soitem in alldepend: 636 | importedso.update(alldepend[soitem]); 637 | a = time.time(); 638 | getIRtmp(name2path[execitem],filloutputdir+"/"); 639 | b = time.time(); 640 | print("getIRtmp:%f"%(b-a)); 641 | onlyfilename = getfilenamefrompath(name2path[execitem]); 642 | testbegintime2 = time.time(); 643 | (exporteddic,detailreport) = translateIR(filloutputdir + "/" + onlyfilename + "idcom",filloutputdir,importedso); 644 | testendtime2 = time.time(); 645 | transtimesum += (testendtime2 - testbegintime2); 646 | if not len(detailreport) == 0 and writefirst: 647 | writefirst = False; 648 | wdetail(detailreportfile,firmname); 649 | wdetail(detailreportfile,execitem); 650 | wdetail(detailreportfile,name2path[execitem],detailreport); 651 | summurycount(detailreport,summtable); 652 | elif not len(detailreport) == 0: 653 | wdetail(detailreportfile,execitem); 654 | wdetail(detailreportfile,name2path[execitem],detailreport); 655 | summurycount(detailreport,summtable); 656 | testendtime = time.time(); 657 | print("systemconstructtime %f"%(testendtime - testbegintime - transtimesum)); 658 | detailre = dict(); 659 | #print(name2path); 660 | for randitem in ousingrandset: 661 | detailre[randitem] = ("using static seed for rand",5,"using static seed for rand"); 662 | wdetail(detailreportfile,name2path[randitem],detailre); 663 | summurycount(detailre,summtable); 664 | #print(summtable); 665 | wfsummury(summuaryreportfile,firmname,summtable); 666 | return result; 667 | 668 | 669 | if __name__ == "__main__": 670 | if not len(sys.argv) == 6: 671 | print("Usage: (absolution path only)"); 672 | sys.exit(-1); 673 | inputpath = sys.argv[1]; 674 | tmppath = sys.argv[2]; 675 | outputpath = sys.argv[3]; 676 | irpath = sys.argv[4]; 677 | allreportpath = sys.argv[5]; 678 | globalpath = allreportpath; 679 | numextracted = 0; 680 | #os.system("rm -rf " + tmppath); 681 | #os.system("rm -rf " + outputpath); 682 | os.system("rm -rf " + irpath); 683 | a = time.time(); 684 | testr = dfs_dir(inputpath,tmppath,operationf=decompress,operationd = None); 685 | testr = dfs_dir(tmppath,outputpath,operationf=extractfile,operationd = None); 686 | b = time.time(); 687 | print("unpack time:%f"%(b-a)); 688 | testr = dfs_dir(outputpath,irpath,operationf = None, operationd = systemconstruct); 689 | wfsummury(allreportpath,"allsummary",allruleresult); 690 | print("decompressfile:%d"%numdecompress); 691 | dmsg = "decompressfile:%d"%numdecompress; 692 | print("numfirmware:%d"%numfirmware); 693 | numfirmwaremsg = "numfirmware:%d"%numfirmware; 694 | print("extracted:%d"%numextracted); 695 | extractednum = "extracted:%d"%numextracted; 696 | #wfsummury(allreportpath,numfirmwaremsg); 697 | #wfsummury(allreportpath,extractednum); 698 | 699 | '''testr = dfs_dir(outputpath,irpath,operationf=filterfile); 700 | testr = dfs_dir(outputpath,irpath); 701 | print("ir%s\n"%(irpath)); 702 | testr = dfs_dir(outputpath,irtmppath,operationf=getIRtmp); 703 | testr = dfs_dir(irtmppath,irpath,operationf=translateIR); 704 | wfsummury(allreportpath,allruleresult);''' 705 | -------------------------------------------------------------------------------- /rex/problock.py: -------------------------------------------------------------------------------- 1 | import angr 2 | 3 | import copy 4 | 5 | 6 | class ARGTYPE: 7 | Voffset = 1, 8 | Vaddr = 2, 9 | Vconst = 3, 10 | Vtmp = 4, 11 | Vstackv = 5, 12 | Vunkown = 6 13 | 14 | class FARGTYPE: 15 | Vstring = 1, 16 | Vint = 2, 17 | Vlen = 3, 18 | Vnone = 4 19 | 20 | class funcop: 21 | def __init__(self): 22 | self.functionname = ""; 23 | self.src = 0; 24 | self.len = 0; 25 | self.dest = 0; 26 | self.srctype = 0; 27 | self.desttype = 0, 28 | self.returntype = ""; 29 | 30 | def setfunctionname(self,funcname): 31 | self.functionname = funcname; 32 | 33 | def getfunctionname(self): 34 | return self.functionname; 35 | 36 | def setfuncsrc(self,funcsrc): 37 | self.src = funcsrc; 38 | 39 | def getfuncsrc(self): 40 | return self.src; 41 | 42 | def setfunclen(self,funclen): 43 | self.len = funclen; 44 | 45 | def getfunclen(self): 46 | return self.funclen; 47 | 48 | def setfuncdest(self,funcdest): 49 | self.dest = funcdest; 50 | 51 | def getfuncdest(self): 52 | return self.dest; 53 | 54 | def getreturntype(self): 55 | return self.returntype; 56 | 57 | def setreturntype(self,funcreturntype): 58 | self.returntype = funcreturntype; 59 | 60 | def setsrctype(self,srctype): 61 | self.srctype = srctype; 62 | 63 | def setdesttype(self,desttype): 64 | self.desttype = desttype; 65 | 66 | def getsrctype(self): 67 | return self.srctype; 68 | 69 | def getdesttype(self): 70 | return self.desttype; 71 | 72 | def listpp(self): 73 | msg = ""; 74 | msg += "functionname:%s "%self.functionname; 75 | msg += " src:%d "%self.src; 76 | if self.srctype == FARGTYPE.Vstring: 77 | msg += " string "; 78 | elif self.srctype == FARGTYPE.Vint: 79 | msg += " int "; 80 | msg += " dest:%d "%self.dest; 81 | if self.desttype == FARGTYPE.Vstring: 82 | msg += " string "; 83 | elif self.desttype == FARGTYPE.Vint: 84 | msg += " int "; 85 | msg += " len:%d "%self.len; 86 | print(msg); 87 | 88 | class function: 89 | def __init__(self): 90 | self.functionname = ""; 91 | self.addr = list(); 92 | self.arg = list(); 93 | self.farg = list(); 94 | self.aargloffset = list(); 95 | self.rule=list(); 96 | self.ruledes=list(); 97 | self.limitl=list(); 98 | self.functiontype = ""; 99 | self.returntype = ""; 100 | 101 | def addlimit(self,limit): 102 | self.limitl.append(limit); 103 | 104 | def getlimitindex(self,index): 105 | return self.limitl[index]; 106 | 107 | def getrule(self): 108 | return self.rule; 109 | 110 | def setrule(self,rule): 111 | self.rule = rule; 112 | 113 | def addruledes(self,ruledesitem): 114 | self.ruledes.append(ruledesitem); 115 | 116 | def addrule(self,rulel): 117 | self.rule.append(rulel); 118 | 119 | def getruleindex(self,index): 120 | return self.rule[index]; 121 | 122 | def getruledesindex(self,index): 123 | return self.ruledes[index]; 124 | 125 | def getfunctionname(self): 126 | return self.functionname; 127 | 128 | def setfunctionname(self,functionname): 129 | self.functionname = functionname; 130 | 131 | def getfunctiontype(self): 132 | return self.functiontype; 133 | 134 | def setfunctiontype(self,functiontype): 135 | self.functiontype = functiontype; 136 | 137 | def getarg(self): 138 | return self.arg; 139 | 140 | def addarg(self,arg): 141 | self.arg.append(arg); 142 | 143 | def fillarg(self,argitem,index): 144 | while len(self.arg) <= index: 145 | self.arg.append(""); 146 | self.arg[index] = argitem; 147 | 148 | def addfarg(self,arg): 149 | self.farg.append(arg); 150 | 151 | def getfarg(self): 152 | return self.farg; 153 | 154 | def farglen(self): 155 | return len(self.farg); 156 | 157 | def getfargitem(self,index): 158 | return self.farg[index]; 159 | 160 | def setreturntype(self,returntype): 161 | self.returntype = returntype; 162 | 163 | def getreturntype(self): 164 | return self.returntype; 165 | 166 | def getfunctionaddr(self): 167 | return self.addr; 168 | 169 | def addfunctionaddr(self,addr): 170 | if not addr in self.addr: 171 | self.addr.append(addr); 172 | 173 | def clearfunctionaarg(self): 174 | self.aargloffset = list(); 175 | 176 | def addfunctionaarg(self,offset): 177 | self.aargloffset.append(offset); 178 | 179 | def getfunctionaarg(self,locat): 180 | if len(self.aargloffset) <= locat: 181 | return None; 182 | return self.aargloffset[locat]; 183 | 184 | def setfunctionaargoffset(self,locat,v): 185 | if len(self.aargloffset) <= locat: 186 | return False; 187 | self.aargloffset[locat] = v; 188 | return True; 189 | 190 | def getfunctionaarglist(self): 191 | return self.aargloffset; 192 | 193 | def listallfagrpp(self): 194 | print(self.functionname); 195 | '''for i in range(0,len(self.addr)): 196 | msg = ""; 197 | msg += "addr:0x%X "%self.addr[i]; 198 | print(msg);''' 199 | for fargitemindex in range(0,len(self.farg)): 200 | msg = ""; 201 | fargitem = self.farg[fargitemindex]; 202 | faddrv = fargitem[0]; 203 | faddrtype = fargitem[1]; 204 | msg += " faddr:%d"%faddrv; 205 | msg += " faddrtype:%d"%faddrtype; 206 | msg += " limit:%s"%self.limitl[fargitemindex]; 207 | msg += " rule:%d"%self.rule[fargitemindex]; 208 | msg += " ruledes:%s"%self.ruledes[fargitemindex]; 209 | #msg += "" 210 | print(msg); 211 | 212 | class FUNCTIONTYPE: 213 | inner = 1, 214 | extern = 2 215 | 216 | 217 | class CHILDRENSIZE: 218 | Vexit = 1, 219 | Vnext = 2, 220 | Vlr = 3 221 | 222 | class CHILRENSLIDE: 223 | Vleft = 1, 224 | Vright = 2 225 | 226 | class traceinfo: 227 | def __init__(self): 228 | self.functionname = "" 229 | self.vl = list(); 230 | self.vtypel = list(); 231 | self.metal = list(); 232 | self.needtrace = list(); 233 | self.argtypel = list(); 234 | self.fresultl = list(); 235 | self.faddrl = list(); 236 | self.rulel = list(); 237 | self.ruledesl = list(); 238 | self.calleaddr = list(); 239 | self.nop = list(); 240 | self.frulel = list(); 241 | self.map = dict(); 242 | 243 | def addalllist(self,v,vtype,meta,argtype,calleaddr,rule,ruledes,fr=""): 244 | index = len(self.vl); 245 | self.vl.append(v); 246 | self.vtypel.append(vtype); 247 | if argtype == FARGTYPE.Vnone: 248 | self.needtrace.append(False); 249 | else: 250 | self.needtrace.append(True); 251 | self.nop.append(True); 252 | self.metal.append(meta); 253 | self.argtypel.append(argtype); 254 | self.fresultl.append(""); 255 | self.faddrl.append(0x0); 256 | self.calleaddr.append(calleaddr); 257 | self.rulel.append(rule); 258 | self.ruledesl.append(ruledes); 259 | self.frulel.append(fr); 260 | self.map[str(v) +" " + str(vtype)] = index; 261 | 262 | def getallitem(self,index): 263 | if index < 0 or index >= self.alllen(): 264 | return None; 265 | return self.vl[index],self.vtypel[index],self.metal[index],self.needtrace[index],self.argtypel[index],self.fresultl[index],self.faddrl[index],self.rulel[index],self.ruledesl[index],self.calleaddr[index],self.nop[index],self.frulel[index] 266 | 267 | def keyin(self,v,vtype): 268 | if str(v) + " " + str(vtype) in self.map: 269 | return True; 270 | return False; 271 | 272 | def keyupdate(self,v,vtype,nv,nvtype): 273 | if not self.keyin(v,vtype): 274 | return False; 275 | index = self.map[str(v) + " " + str(vtype)]; 276 | del self.map[str(v) +" " + str(vtype)]; 277 | self.map[str(nv) + " " + str(nvtype)] = index; 278 | self.vl[index] = nv; 279 | self.vtypel[index] = nvtype; 280 | return True; 281 | 282 | def keyadddup(self,v,vtype,nv,nvtype): 283 | if not self.keyin(v,vtype): 284 | return False; 285 | index = self.map[str(v) + " " + str(vtype)]; 286 | self.map[str(nv) + " " + str(nvtype)] = index; 287 | return True; 288 | 289 | def setfunctionname(self,fn): 290 | self.functionname = fn; 291 | 292 | def getfunctionname(self): 293 | return self.functionname; 294 | 295 | def alllen(self): 296 | return len(self.vl); 297 | 298 | def getindexvl(self,index): 299 | return self.vl[index]; 300 | 301 | def getindexvtypel(self,index): 302 | return self.vtypel[index]; 303 | 304 | def setntrace(self,v,vtype): 305 | if not self.keyin(v,vtype): 306 | return None; 307 | index = self.map[str(v) + " " + str(vtype)]; 308 | self.needtrace[index] = False; 309 | 310 | def gettrace(self,v,vtype): 311 | if not self.keyin(v,vtype): 312 | return None; 313 | index = self.map[str(v) + " " + str(vtype)]; 314 | return self.needtrace[index]; 315 | 316 | def setfresult(self,v,vtype,result): 317 | if not self.keyin(v,vtype): 318 | return None; 319 | index = self.map[str(v) + " " + str(vtype)]; 320 | self.fresultl[index] = result; 321 | 322 | def setnprint(self,v,vtype): 323 | if not self.keyin(v,vtype): 324 | return None; 325 | index = self.map[str(v) + " " + str(vtype)]; 326 | self.nop[index] = False; 327 | 328 | 329 | def getfresult(self,v,vtype): 330 | if not self.keyin(v,vtype): 331 | return None; 332 | index = self.map[str(v) + " " + str(vtype)]; 333 | #print(index); 334 | return self.fresultl[index]; 335 | 336 | def setfaddr(self,v,vtype,fa): 337 | if not self.keyin(v,vtype): 338 | return None; 339 | index = self.map[str(v) + " " + str(vtype)]; 340 | self.faddrl[index] = fa; 341 | 342 | def getfaddr(self,v,vtype): 343 | if not self.keyin(v,vtype): 344 | return None; 345 | index = self.map[str(v) + " " + str(vtype)]; 346 | return self.faddrl[index]; 347 | 348 | def setmeta(self,v,vtype,meta): 349 | if not self.keyin(v,vtype): 350 | return None; 351 | index = self.map[str(v) + " " + str(vtype)]; 352 | self.metal[index] = meta; 353 | 354 | def getmeta(self,v,vtype): 355 | if not self.keyin(v,vtype): 356 | return None; 357 | index = self.map[str(v) + " " + str(vtype)]; 358 | return self.metal[index]; 359 | 360 | def setargtype(self,v,vtype,argtype): 361 | if not self.keyin(v,vtype): 362 | return None; 363 | index = self.map[str(v) + " " + str(vtype)]; 364 | self.argtypel[index] = argtype; 365 | 366 | def getargtype(self,v,vtype): 367 | if not self.keyin(v,vtype): 368 | return None; 369 | index = self.map[str(v) + " " + str(vtype)]; 370 | return self.argtypel[index]; 371 | 372 | def getcalleaddr(self,v,vtype): 373 | if not self.keyin(v,vtype): 374 | return None; 375 | index = self.map[str(v) + " " + str(vtype)]; 376 | return self.calleaddr[index]; 377 | 378 | def setcalleaddr(self,v,vtype,addr): 379 | if not self.keyin(v,vtype): 380 | return None; 381 | index = self.map[str(v) + " " + str(vtype)]; 382 | self.argtypel[index] = addr; 383 | 384 | def settntrace(self): 385 | for i in range(0,len(self.vl)): 386 | if not self.vtypel[i] == ARGTYPE.Voffset and not self.vtypel[i]==ARGTYPE.Vstackv: 387 | self.needtrace[i] = False; 388 | self.nop[i] = False; 389 | 390 | def listallpp(self,dt): 391 | msg = ""; 392 | for i in range(0,len(self.vl)): 393 | if not self.nop[i] or self.needtrace[i]: 394 | continue; 395 | self.nop[i] = False; 396 | if self.argtypel[i] == FARGTYPE.Vstring and not isinstance(self.fresultl[i],str): 397 | continue; 398 | elif self.argtypel[i] == FARGTYPE.Vint and not isinstance(self.fresultl[i],int): 399 | continue; 400 | if self.argtypel[i] == FARGTYPE.Vstring and (len(self.fresultl[i]) == 0 or self.fresultl[i] == "" or self.fresultl[i] == None): 401 | continue; 402 | elif self.argtypel[i] == FARGTYPE.Vint and not len(self.frulel[i]) == 0 and isinstance(self.fresultl[i],int): 403 | limit = 0; 404 | if self.frulel[i][0] == "<": 405 | limit = int(self.frulel[i][1:]); 406 | if self.fresultl[i] >= limit: 407 | continue; 408 | elif self.frulel[i][0] == "=": 409 | limit = int(self.frulel[i][1:]); 410 | if not self.fresultl[i] == limit: 411 | continue; 412 | elif self.frulel[i][0] == ">": 413 | limit = int(self.frulel[i][1:]); 414 | if self.fresultl[i] <= limit: 415 | continue; 416 | msg += "v:%d "%self.vl[i]; 417 | msg += "functionname:%s "%self.functionname; 418 | msg += "meta:%s "%self.metal[i]; 419 | msg += "vtype:%d "%self.vtypel[i]; 420 | msg += "argtype:%d "%self.argtypel[i]; 421 | msg += "calleaddr:0x%X "%self.calleaddr[i]; 422 | msg += "faddr:0x%X "%self.faddrl[i]; 423 | msg += "fresult:%s "%self.fresultl[i]; 424 | msg += "rule:%s "%self.rulel[i]; 425 | msg += "ruledes:%s "%self.ruledesl[i]; 426 | '''if self.needtrace[i]: 427 | msg += "needtrace "; 428 | else: 429 | msg += "noneedtrace "''' 430 | #msg += "index:%d "%self.map[str(self.vl[i]) + " " + str(self.vtypel[i])] 431 | print("listallpp"); 432 | print(msg); 433 | dt[str(self.functionname)+str(self.faddrl[i])+str(self.metal[i])+str(self.calleaddr[i])+str(self.fresultl[i])] = (msg,self.rulel[i],self.ruledesl[i]); 434 | #print(len(self.fresultl[i])); 435 | msg = ""; 436 | 437 | def listdebugpp(self): 438 | msg = ""; 439 | for i in range(0,len(self.vl)): 440 | '''if not self.nop[i] or self.needtrace[i]: 441 | continue; 442 | self.nop[i] = False; 443 | if self.argtypel[i] == FARGTYPE.Vstring and (len(self.fresultl[i]) == 0 or self.fresultl[i] == "" or self.fresultl[i] == None): 444 | continue; 445 | elif self.argtypel[i] == FARGTYPE.Vint and not len(self.frulel[i]) == 0 and isinstance(self.fresultl[i],int): 446 | limit = 0; 447 | if self.frulel[i][0] == "<": 448 | limit = int(self.frulel[i][1:]); 449 | if self.fresultl[i] >= limit: 450 | continue; 451 | elif self.frulel[i][0] == "=": 452 | limit = int(self.frulel[i][1:]); 453 | if not self.fresultl[i] == limit: 454 | continue; 455 | elif self.frulel[i][0] == ">": 456 | limit = int(self.frulel[i][1:]); 457 | if self.fresultl[i] <= limit: 458 | continue;''' 459 | msg += "v:%d "%self.vl[i]; 460 | msg += "functionname:%s "%self.functionname; 461 | msg += "meta:%s "%self.metal[i]; 462 | msg += "vtype:%d "%self.vtypel[i]; 463 | msg += "argtype:%d "%self.argtypel[i]; 464 | msg += "calleaddr:0x%X "%self.calleaddr[i]; 465 | msg += "faddr:0x%X "%self.faddrl[i]; 466 | msg += "fresult:%s "%self.fresultl[i]; 467 | msg += "rule:%s "%self.rulel[i]; 468 | msg += "ruledes:%s "%self.ruledesl[i]; 469 | if self.needtrace[i]: 470 | msg += "needtrace "; 471 | else: 472 | msg += "noneedtrace " 473 | #msg += "index:%d "%self.map[str(self.vl[i]) + " " + str(self.vtypel[i])] 474 | print(msg); 475 | #dt[str(self.functionname)+str(self.faddrl[i])+str(self.metal[i])+str(self.calleaddr[i])+str(self.fresultl[i])] = (msg,self.rulel[i],self.ruledesl[i]); 476 | #print(len(self.fresultl[i])); 477 | msg = ""; 478 | 479 | def ntlen(self): 480 | result = 0; 481 | for nitem in self.needtrace: 482 | if nitem: 483 | result += 1; 484 | return result; 485 | 486 | def ntlen(self): 487 | result = 0; 488 | for nitem in self.needtrace: 489 | if nitem: 490 | result += 1; 491 | return result; 492 | 493 | 494 | def traceinfocopy(tis): 495 | tit = traceinfo(); 496 | tit.vl = copy.copy(tis.vl); 497 | tit.vtypel = copy.copy(tis.vtypel); 498 | tit.metal = copy.copy(tis.metal); 499 | tit.needtrace = copy.copy(tis.needtrace); 500 | tit.argtypel = copy.copy(tis.argtypel); 501 | tit.fresultl = copy.copy(tis.fresultl); 502 | tit.faddrl = copy.copy(tis.faddrl); 503 | tit.nop = copy.copy(tis.nop); 504 | tit.map = copy.copy(tis.map); 505 | #tit.vlenl = copy.copy(tis.vlenl); 506 | tit.calleaddr = copy.copy(tis.calleaddr); 507 | tit.rulel = copy.copy(tis.rulel); 508 | tit.ruledesl = copy.copy(tis.ruledesl); 509 | tit.frulel = copy.copy(tis.frulel); 510 | tit.functionname = tis.functionname; 511 | return tit; 512 | 513 | def finishfuncdetail(function,pnode): 514 | function.clearfunctionaarg(); 515 | if len(function.getarg()) <= 4: 516 | comlist = pnode.getcomarglist(); 517 | for i in range(0,len(function.getarg())): 518 | function.addfunctionaarg([comlist[i],ARGTYPE.Voffset]); 519 | else: 520 | aargnum = len(function.getarg()); 521 | comlist = pnode.getcomarglist(); 522 | for i in range(0,4): 523 | function.addfunctionaarg([comlist[i],ARGTYPE.Voffset]); 524 | for i in range(4,aargnum): 525 | function.addfunctionaarg([i-4,ARGTYPE.Vstackv]); 526 | 527 | def func2traceinfo(function,beginaddr): 528 | ti = traceinfo(); 529 | functionname = function.getfunctionname(); 530 | ti.setfunctionname(functionname); 531 | functionargl = function.getfunctionaarglist(); 532 | indexi = 0; 533 | for fargitemindex in range(0,function.farglen()): 534 | fargitem = function.getfargitem(fargitemindex); 535 | index = fargitem[0] - 1; 536 | v = -1; 537 | vtype = ARGTYPE.Vunkown; 538 | if index < len(functionargl) and index >= 0: 539 | v = functionargl[index][0]; 540 | vtype = functionargl[index][1]; 541 | vmeta = " arg (" + function.getarg()[index] + ")"; 542 | vargtype = fargitem[1]; 543 | rule = function.getruleindex(indexi); 544 | ruledes = function.getruledesindex(indexi); 545 | limit = function.getlimitindex(indexi); 546 | ti.addalllist(v,vtype,vmeta,vargtype,beginaddr,rule,ruledes,limit); 547 | indexi += 1; 548 | return ti; 549 | 550 | def traceinfo2func(ti,node,functionname): 551 | fn = function(); 552 | fn.setfunctionname(functionname); 553 | for i in range(0,ti.alllen()): 554 | v,vtype,metal,needtrace,argtype,fresult,faddr,rule,ruledes,calleaddr,nop,limit = ti.getallitem(i); 555 | if not needtrace: 556 | continue; 557 | argnumleast = 0; 558 | if vtype == ARGTYPE.Voffset and v in node.comarglist: 559 | argindex = node.comarglist.index(v) + 1; 560 | fn.addfarg([argindex,argtype]); 561 | argnumleast = argindex - 1; 562 | elif vtype == ARGTYPE.Vstackv: 563 | pass; 564 | if argtype == FARGTYPE.Vstring: 565 | fn.fillarg("string",argnumleast); 566 | elif argtype == FARGTYPE.Vint: 567 | fn.fillarg("int",argnumleast); 568 | fn.setreturntype(""); 569 | fn.addrule(rule); 570 | fn.addruledes(ruledes); 571 | fn.addlimit(limit); 572 | finishfuncdetail(fn,node); 573 | return fn; 574 | 575 | class functioncontainer: 576 | def __init__(self): 577 | self.functions = list(); 578 | self.functionsdic = dict(); 579 | 580 | def addfunction(self,function): 581 | if function.getfunctionname() in self.functionsdic or any(s in function.getfunctionaddr() for s in self.functionsdic.keys()): 582 | return; 583 | index = len(self.functions); 584 | self.functions.append(function); 585 | self.functionsdic[function.getfunctionname()] = index; 586 | for addr in function.getfunctionaddr(): 587 | self.functionsdic[str(addr)] = index; 588 | 589 | def getfunction(self,info): 590 | if not info in self.functionsdic: 591 | return None; 592 | index = self.functionsdic[info]; 593 | return self.functions[index]; 594 | 595 | def addfunctionaddr(self,name,addr): 596 | if not name in self.functionsdic or addr in self.functionsdic: 597 | return; 598 | index = self.functionsdic[name]; 599 | self.functionsdic[str(addr)] = index; 600 | 601 | '''def functioncall( filename,blockbegin, instructions): 602 | #print(dir(obj)) 603 | obj = subprocess.Popen(["/usr/bin/r2", filename],stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE); 604 | obj.stdin.write('s ' + blockbegin + '\n'); 605 | obj.stdin.write('pds > /dev/null\n'); 606 | #obj.stdout.read(); 607 | #print('pd ' + instructions + '> /tmp/' + rs +'\n'); 608 | obj.stdin.write('pd ' + instructions + '\n'); 609 | obj.stdin.write('exit\n'); 610 | print(filename); 611 | print(blockbegin); 612 | print(instructions); 613 | #obj.stdin.flush(); 614 | obj.wait(); 615 | 616 | cmd_out = ""; 617 | cmd_out = obj.stdout.read(); 618 | #print("begin"); 619 | #while line: 620 | # cmd_out = line + "\n"; 621 | # line = obj.stdout.readline(); 622 | #print("output"); 623 | #print(cmd_out); 624 | #return ; 625 | #print("end"); 626 | buf = StringIO.StringIO(cmd_out); 627 | #buf = open("/tmp/"+rs,'r'); 628 | line = buf.readline(); 629 | tmpbuf = ""; 630 | while line: 631 | #print(line); 632 | if not line.find("sym") == -1: 633 | tmpbuf = line; 634 | line = buf.readline(); 635 | if tmpbuf == "": 636 | return; 637 | else: 638 | tmpbuf = tmpbuf[tmpbuf.rindex("sym")+len("sym") +1:len(tmpbuf)]; 639 | if not tmpbuf.find(";") == -1: 640 | tmpbuf = tmpbuf[0:tmpbuf.index(";")].strip(); 641 | last = 0; 642 | for x in tmpbuf: 643 | if x not in string.printable: 644 | break; 645 | last += 1; 646 | tmpbuf = tmpbuf[0:last]; 647 | print(tmpbuf);''' 648 | 649 | class problock: 650 | def __init__(self,irsb=None,lcom = None): 651 | self.stack = list(); 652 | self.stackoffset = 0; 653 | self.bpoffset = None; 654 | self.bp_offset = 0; 655 | self.leftchildren = list(); 656 | self.rightchildren = list(); 657 | self.parents = list(); 658 | self.arch = ""; 659 | self.sp = 0; 660 | self.beginaddr = 0; 661 | self.size = 0; 662 | self.iscallextern = False; 663 | self.externfunctioncall = ""; 664 | self.externfunctionarg = list(); 665 | self.externreturnvalue = 0; 666 | self.externactarg = list(); 667 | self.comarglist = list(); 668 | self.argunfixed = list(); 669 | self.returnoffset = 0; 670 | self.lcom = lcom; 671 | self.irsb = irsb; 672 | self.rootpath = list(); 673 | self.maxp = 0; 674 | self.minn = 0; 675 | self.transonce = False; 676 | self.sprelate = dict(); 677 | self.wordlen = 0; 678 | self.stackfixnum = 0x0; 679 | self.bp = 0x0; 680 | self.stackregoffset = dict(); 681 | self.soff = 0; 682 | self.bl = 0; 683 | if not irsb == None: 684 | self.arch = self.irsb.arch; 685 | self.sp = self.irsb.arch.sp_offset; 686 | self.bp = self.irsb.arch.bp_offset; 687 | self.beginaddr = self.irsb.addr; 688 | self.size = self.irsb.size; 689 | self.iscallextern = False; 690 | self.externfunctioncall = ""; 691 | self.externfunctionarg = list(); 692 | self.externreturnvalue = 0; 693 | self.externactarg = list(); 694 | if self.irsb.arch.vex_arch == "VexArchARM": 695 | self.comarglist.append(self.irsb.arch.get_register_offset("r0")); 696 | self.comarglist.append(self.irsb.arch.get_register_offset("r1")); 697 | self.comarglist.append(self.irsb.arch.get_register_offset("r2")); 698 | self.comarglist.append(self.irsb.arch.get_register_offset("r3")); 699 | self.returnoffset = self.irsb.arch.get_register_offset("r0"); 700 | self.argunfixed.append(self.irsb.arch.get_register_offset("r0")); 701 | self.argunfixed.append(self.irsb.arch.get_register_offset("r1")); 702 | self.argunfixed.append(self.irsb.arch.get_register_offset("r2")); 703 | self.argunfixed.append(self.irsb.arch.get_register_offset("r3")); 704 | elif self.irsb.arch.vex_arch == "VexArchMIPS32": 705 | self.comarglist.append(self.irsb.arch.get_register_offset("a0")); 706 | self.comarglist.append(self.irsb.arch.get_register_offset("a1")); 707 | self.comarglist.append(self.irsb.arch.get_register_offset("a2")); 708 | self.comarglist.append(self.irsb.arch.get_register_offset("a3")); 709 | self.returnoffset = self.irsb.arch.get_register_offset("v0"); 710 | self.argunfixed.append(self.irsb.arch.get_register_offset("v0")); 711 | self.argunfixed.append(self.irsb.arch.get_register_offset("v1")); 712 | self.argunfixed.append(self.irsb.arch.get_register_offset("a0")); 713 | self.argunfixed.append(self.irsb.arch.get_register_offset("a1")); 714 | self.argunfixed.append(self.irsb.arch.get_register_offset("a2")); 715 | self.argunfixed.append(self.irsb.arch.get_register_offset("a3")); 716 | elif self.irsb.arch.vex_arch == "VexArchMIPSel": 717 | self.comarglist.append(self.irsb.arch.get_register_offset("r0")); 718 | self.comarglist.append(self.irsb.arch.get_register_offset("r1")); 719 | self.comarglist.append(self.irsb.arch.get_register_offset("r2")); 720 | self.comarglist.append(self.irsb.arch.get_register_offset("r3")); 721 | self.returnoffset = self.irsb.arch.get_register_offset("r0"); 722 | self.argunfixed.append(self.irsb.arch.get_register_offset("r0")); 723 | self.argunfixed.append(self.irsb.arch.get_register_offset("r1")); 724 | self.argunfixed.append(self.irsb.arch.get_register_offset("r2")); 725 | self.argunfixed.append(self.irsb.arch.get_register_offset("r3")); 726 | elif self.irsb.arch.vex_arch == "VexArchMIPS64": 727 | self.comarglist.append(self.irsb.arch.get_register_offset("r0")); 728 | self.comarglist.append(self.irsb.arch.get_register_offset("r1")); 729 | self.comarglist.append(self.irsb.arch.get_register_offset("r2")); 730 | self.comarglist.append(self.irsb.arch.get_register_offset("r3")); 731 | self.returnoffset = self.irsb.arch.get_register_offset("r0"); 732 | self.argunfixed.append(self.irsb.arch.get_register_offset("r0")); 733 | self.argunfixed.append(self.irsb.arch.get_register_offset("r1")); 734 | self.argunfixed.append(self.irsb.arch.get_register_offset("r2")); 735 | self.argunfixed.append(self.irsb.arch.get_register_offset("r3")); 736 | elif self.irsb.arch.vex_arch == "VexArchIntel": 737 | self.comarglist.append(self.irsb.arch.get_register_offset("r0")); 738 | self.comarglist.append(self.irsb.arch.get_register_offset("r1")); 739 | self.comarglist.append(self.irsb.arch.get_register_offset("r2")); 740 | self.comarglist.append(self.irsb.arch.get_register_offset("r3")); 741 | self.returnoffset = self.irsb.arch.get_register_offset("r0"); 742 | self.argunfixed.append(self.irsb.arch.get_register_offset("r0")); 743 | self.argunfixed.append(self.irsb.arch.get_register_offset("r1")); 744 | self.argunfixed.append(self.irsb.arch.get_register_offset("r2")); 745 | self.argunfixed.append(self.irsb.arch.get_register_offset("r3")); 746 | self.maxp = 2 ** (self.arch.bits - 1) - 1; 747 | self.minn = -2 ** (self.arch.bits - 1); 748 | self.wordlen = self.irsb.arch.bits / 8; 749 | 750 | def instack(self,v,vtype): 751 | if str(v) + " " + str(vtype) in self.sprelate: 752 | return True; 753 | else: 754 | return False; 755 | 756 | def getstackdata(self,v,vtype): 757 | if not self.instack(v,vtype): 758 | return [0,ARGTYPE.Vunkown]; 759 | else: 760 | return self.stack[self.sprelate[str(v) + " " + str(vtype)]/ self.bl + self.soff]; 761 | 762 | def unfixedarglen(self): 763 | return len(self.argunfixed); 764 | 765 | def getunfixedarg(self,index): 766 | return self.argunfixed[index]; 767 | 768 | def getwordlen(self): 769 | return self.wordlen; 770 | 771 | def setbeginaddr(self,begin): 772 | self.beginaddr=begin; 773 | 774 | def getbeginaddr(self): 775 | return self.beginaddr; 776 | 777 | def getcomarglist(self): 778 | return self.comarglist; 779 | 780 | def getirsb(self): 781 | return self.irsb; 782 | 783 | def tracearg(self,arginfo): 784 | arglist = list(); 785 | argtypelist = list(); 786 | for aitem in arginfo: 787 | arg = arginfo[0]; 788 | argtype = arginfo[1]; 789 | 790 | 791 | def addleftchildren(self,problocknode): 792 | self.leftchildren.append(problocknode); 793 | return CHILRENSLIDE.Vleft,len(self.leftchildren) - 1; 794 | 795 | def addrightchildren(self,problocknode): 796 | self.rightchildren.append(problocknode); 797 | return CHILRENSLIDE.Vright,len(self.rightchildren) - 1; 798 | 799 | def addparents(self,problocknode): 800 | self.parents.append(problocknode); 801 | 802 | def getleftchildren(self): 803 | return self.leftchildren; 804 | 805 | def addrootpath(self,path): 806 | self.rootpath.append(path); 807 | 808 | def getrootpath(self): 809 | return self.rootpath; 810 | 811 | def getrightchildren(self): 812 | return self.rightchildren; 813 | 814 | def getparents(self): 815 | return self.parents; 816 | 817 | def blockstack(self): 818 | pass; 819 | 820 | def exitstate(self): 821 | pass; 822 | 823 | def blockqemuex(self): 824 | pass; 825 | 826 | def addexternflag(self): 827 | self.iscallextern = True; 828 | 829 | def externflag(self): 830 | return self.iscallextern; 831 | 832 | def addexternfun(self,name): 833 | self.externfunctioncall = name; 834 | 835 | def getexternfun(self): 836 | return self.externfunctioncall; 837 | 838 | def addexternfunarg(self,arg): 839 | self.externfunctionarg.append(arg); 840 | 841 | def constrans(self,num): 842 | result = 0; 843 | if num < self.maxp: 844 | result = num; 845 | else: 846 | result = (num - self.maxp) + self.minn - 1; 847 | return result; 848 | def getbpspoffset(self): 849 | if self.bpoffset == None or self.stackoffset == None: 850 | return None; 851 | return self.bpoffset - self.stackoffset; 852 | 853 | def getnextblockaddr(self,spbpoffset=None): 854 | result = list(); 855 | pastaddress = list(); 856 | nowaddress = list(); 857 | tmpresult = list(); 858 | now = None; 859 | past = None; 860 | lrnowaddr=None; 861 | lrpastaddr=None; 862 | lrex=None; 863 | if self.irsb == None: 864 | return result; 865 | vmin = 0; 866 | vmax = 0; 867 | voff = 0; 868 | self.sprelate[str(self.sp) + " " + str(ARGTYPE.Voffset)] = 0; 869 | bytelen = self.irsb.arch.bits / 8; 870 | if not spbpoffset == None: 871 | if spbpoffset > vmax: 872 | while vmax < spbpoffset: 873 | self.stack.append(["",ARGTYPE.Vunkown]); 874 | vmax += 1; 875 | elif spbpoffset < vmin: 876 | voff = - spbpoffset; 877 | while spbpoffset < vmin: 878 | self.stack.insert(0,["",ARGTYPE.Vunkown]); 879 | vmin -= 1; 880 | self.sprelate[str(self.bp) + " " + str(ARGTYPE.Voffset)] = spbpoffset * self.getwordlen(); 881 | 882 | self.stack.append(["",ARGTYPE.Vunkown]); 883 | for sitem in self.irsb.statements: 884 | if sitem.tag == "Ist_IMark": 885 | past = now; 886 | now = sitem.addr; 887 | elif sitem.tag == "Ist_Exit": 888 | tmpresult.append([sitem,CHILDRENSIZE.Vexit]); 889 | nowaddress.append(now); 890 | pastaddress.append(past); 891 | elif sitem.tag == "Ist_Put": 892 | if sitem.offset == self.arch.lr_offset and self.irsb.jumpkind == "Ijk_Call": 893 | for ex in sitem.expressions: 894 | if ex.tag == "Iex_Const": 895 | lrnowaddr=now; 896 | lrpastaddr=past; 897 | lrex=ex; 898 | for ex in sitem.expressions: 899 | if ex.tag == "Iex_RdTmp": 900 | if str(ex.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate: 901 | self.stackregoffset[sitem.offset] = self.sprelate[str(ex.tmp) + " " + str(ARGTYPE.Vtmp)]; 902 | if not str(ex.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate and sitem.offset in self.stackregoffset: 903 | del self.stackregoffset[sitem.offset]; 904 | # for stack 905 | if self.transonce: 906 | continue; 907 | stackvtmp = 0; 908 | if sitem.tag == "Ist_WrTmp": 909 | eitem = sitem.data; 910 | if eitem.tag == "Iex_Unop": 911 | pass; 912 | elif eitem.tag == "Iex_RdTmp": 913 | pass; 914 | elif eitem.tag == "Iex_Load": 915 | pass; 916 | elif eitem.tag == "Iex_Const": 917 | pass; 918 | elif eitem.tag == "Iex_Binop": 919 | if eitem.op == "Iop_Add32": 920 | arg1 = eitem.args[0]; 921 | arg2 = eitem.args[1]; 922 | if arg1.tag == "Iex_RdTmp" and str(arg1.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate and arg2.tag == "Iex_Const": 923 | stackvtmp = self.sprelate[str(arg1.tmp) + " " + str(ARGTYPE.Vtmp)] + self.constrans(arg2.constants[0].value); 924 | if stackvtmp / bytelen > vmax: 925 | while vmax < stackvtmp / bytelen: 926 | self.stack.append(["",ARGTYPE.Vunkown]); 927 | vmax += 1; 928 | elif stackvtmp / bytelen < vmin: 929 | voff = - stackvtmp / bytelen; 930 | while stackvtmp / bytelen < vmin: 931 | self.stack.insert(0,["",ARGTYPE.Vunkown]); 932 | vmin -= 1; 933 | self.sprelate[str(sitem.tmp) + " " + str(ARGTYPE.Vtmp)] = stackvtmp; 934 | elif arg2.tag == "Iex_RdTmp" and str(arg2.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate and arg1.tag == "Iex_Const": 935 | stackvtmp = self.sprelate[str(arg2.tmp) + " " + str(ARGTYPE.Vtmp)] + self.constrans(arg1.constants[0].value); 936 | if stackvtmp / bytelen > vmax: 937 | while vmax < stackvtmp / bytelen: 938 | self.stack.append(["",ARGTYPE.Vunkown]); 939 | vmax += 1; 940 | elif stackvtmp / bytelen < vmin: 941 | voff = - stackvtmp / bytelen; 942 | while stackvtmp / bytelen < vmin: 943 | self.stack.insert(0,["",ARGTYPE.Vunkown]); 944 | vmin -= 1; 945 | self.sprelate[str(sitem.tmp) + " " + str(ARGTYPE.Vtmp)] = stackvtmp; 946 | elif eitem.op == "Iop_Sub32": 947 | arg1 = eitem.args[0]; 948 | arg2 = eitem.args[1]; 949 | if arg1.tag == "Iex_RdTmp" and str(arg1.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate and arg2.tag == "Iex_Const": 950 | stackvtmp = self.sprelate[str(arg1.tmp) + " " + str(ARGTYPE.Vtmp)] - self.constrans(arg2.constants[0].value); 951 | if stackvtmp / bytelen > vmax: 952 | while vmax < stackvtmp / bytelen: 953 | self.stack.append(["",ARGTYPE.Vunkown]); 954 | vmax += 1; 955 | elif stackvtmp / bytelen < vmin: 956 | voff = - stackvtmp / bytelen; 957 | while stackvtmp / bytelen < vmin: 958 | self.stack.insert(0,["",ARGTYPE.Vunkown]); 959 | vmin -= 1; 960 | self.sprelate[str(sitem.tmp) + " " + str(ARGTYPE.Vtmp)] = stackvtmp; 961 | elif arg2.tag == "Iex_RdTmp" and str(arg2.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate and arg1.tag == "Iex_Const": 962 | stackvtmp = self.sprelate[str(arg2.tmp) + " " + str(ARGTYPE.Vtmp)] - self.constrans(arg1.constants[0].value); 963 | if stackvtmp / bytelen > vmax: 964 | while vmax < stackvtmp / bytelen: 965 | self.stack.append(["",ARGTYPE.Vunkown]); 966 | vmax += 1; 967 | elif stackvtmp / bytelen < vmin: 968 | voff = - stackvtmp / bytelen; 969 | while stackvtmp / bytelen < vmin: 970 | self.stack.insert(0,["",ARGTYPE.Vunkown]); 971 | vmin -= 1; 972 | self.sprelate[str(sitem.tmp) + " " + str(ARGTYPE.Vtmp)] = stackvtmp; 973 | elif eitem.tag == "Iex_Get": 974 | if str(eitem.offset) + " " + str(ARGTYPE.Voffset) in self.sprelate: 975 | stackvtmp = self.sprelate[str(eitem.offset) + " " + str(ARGTYPE.Voffset)]; 976 | if stackvtmp / bytelen > vmax: 977 | while vmax < stackvtmp / bytelen: 978 | self.stack.append(["",ARGTYPE.Vunkown]); 979 | vmax += 1; 980 | elif stackvtmp / bytelen < vmin: 981 | voff = - stackvtmp / bytelen; 982 | while stackvtmp / bytelen < vmin: 983 | self.stack.insert(0,["",ARGTYPE.Vunkown]); 984 | vmin -= 1; 985 | self.sprelate[str(sitem.tmp) + " " + str(ARGTYPE.Vtmp)] = stackvtmp; 986 | elif sitem.tag == "Ist_Store": 987 | destt = sitem.addr; 988 | srct = sitem.data; 989 | if destt.tag == "Iex_RdTmp" and srct.tag == "Iex_RdTmp": 990 | if str(destt.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate: 991 | self.stack[self.sprelate[str(destt.tmp) + " " + str(ARGTYPE.Vtmp)] / bytelen + voff] = [srct.tmp,ARGTYPE.Vtmp]; 992 | elif destt.tag == "Iex_RdTmp" and srct.tag == "Iex_Const": 993 | if str(destt.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate: 994 | self.stack[self.sprelate[str(destt.tmp) + " " + str(ARGTYPE.Vtmp)] / bytelen + voff] = [srct.constants[0].value,ARGTYPE.Vconst]; 995 | elif sitem.tag == "Ist_Put": 996 | if sitem.offset == self.arch.sp_offset and sitem.data.tag == "Iex_RdTmp" and str(sitem.data.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate: 997 | self.stackoffset = self.sprelate[str(sitem.data.tmp) + " " + str(ARGTYPE.Vtmp)] / bytelen; 998 | if sitem.offset == self.arch.bp_offset and sitem.data.tag == "Iex_RdTmp" and str(sitem.data.tmp) + " " + str(ARGTYPE.Vtmp) in self.sprelate: 999 | self.bpoffset = self.sprelate[str(sitem.data.tmp) + " " + str(ARGTYPE.Vtmp)]/bytelen; 1000 | self.soff = voff; 1001 | self.bl = bytelen; 1002 | self.stackfixnum = -vmin; 1003 | self.transonce = True; 1004 | nowaddress.append(now); 1005 | pastaddress.append(past); 1006 | tmpresult.append([self.irsb.next,CHILDRENSIZE.Vnext]); 1007 | #if self.beginaddr == 0x1056c or self.beginaddr == 0x10550: 1008 | # print("stack:0x%X"%self.beginaddr); 1009 | # print(self.stack); 1010 | # print(self.sprelate); 1011 | # print(self.bpoffset); 1012 | # print(self.stackoffset); 1013 | if not lrex == None: 1014 | nowaddress.append(lrnowaddr); 1015 | pastaddress.append(lrpastaddr); 1016 | tmpresult.append([lrex,CHILDRENSIZE.Vlr]); 1017 | 1018 | for i in range(0,len(tmpresult)): 1019 | sitem = tmpresult[i][0]; 1020 | slide = tmpresult[i][1]; 1021 | if sitem.tag == "Ist_Exit": 1022 | if sitem.dst.tag == "Ico_U32": 1023 | result.append([str(sitem.dst.value),slide]); 1024 | elif sitem.tag == "Iex_Const": 1025 | for tmpcon in sitem.constants: 1026 | result.append([str(tmpcon.value),slide]); 1027 | elif sitem.tag == "Iex_RdTmp": 1028 | nowaddr = nowaddress[i]; 1029 | pastaddr = pastaddress[i]; 1030 | nextaddr = self.translatetmp2function(nowaddr,pastaddr); 1031 | if nextaddr == None: 1032 | pass; 1033 | else: 1034 | result.append([nextaddr,slide]); 1035 | return result; 1036 | 1037 | 1038 | def translatetmp2function(self,nowaddr,pastaddr): 1039 | if nowaddr in self.lcom and self.lcom[nowaddr][0] == ";" and not len(self.lcom[nowaddr]) == 0: 1040 | return self.lcom[nowaddr][1:]; 1041 | elif pastaddr in self.lcom and self.lcom[pastaddr][0] == ";" and not len(self.lcom[pastaddr]) == 0: 1042 | return self.lcom[pastaddr][1:]; 1043 | return None; 1044 | 1045 | def getstr(self): 1046 | result = ""; 1047 | #for sitem in self.irsb.statements: 1048 | # print(123); 1049 | # print(sitem); 1050 | if not self.irsb == None: 1051 | result += self.irsb._pp_str()+"\n"; 1052 | #print(dir(self.irsb)); 1053 | result += str(self.irsb.direct_next) + "\n"; 1054 | result += str(self.irsb.next) + "\n"; 1055 | nextblocks = self.getnextblockaddr(); 1056 | for b in nextblocks: 1057 | result += b[0] + "\n"; 1058 | if self.transonce: 1059 | result += "%s\n"%self.stack; 1060 | result += "%s\n"%self.sprelate; 1061 | return result; 1062 | 1063 | def getmetadata(self): 1064 | result = ""; 1065 | if not self.irsb == None: 1066 | result += "0x%X"%self.beginaddr; 1067 | elif self.iscallextern: 1068 | result += self.externfunctioncall; 1069 | for a in self.externfunctionarg: 1070 | result += " " + a; 1071 | return result; 1072 | 1073 | def _pp_str(self): 1074 | result = ""; 1075 | result += self.irsb._pp_str() + "\n"; 1076 | return result; 1077 | 1078 | 1079 | def deepcopyproblock(node,leafresult): 1080 | if node == None: 1081 | return None; 1082 | targetnode = problock(node.irsb,node.lcom); 1083 | lefttargetnode = None; 1084 | righttargetnode = None; 1085 | #print("0x%X"%node.beginaddr); 1086 | if node.getleftchildren() == None and node.getrightchildren() == None: 1087 | leafresult.add(targetnode); 1088 | if not node.getleftchildren() == None: 1089 | lefttargetnode = deepcopyproblock(node.getleftchildren(),leafresult); 1090 | targetnode.addleftchildren(lefttargetnode); 1091 | lefttargetnode.addparents(targetnode); 1092 | if not node.getrightchildren() == None: 1093 | righttargetnode = deepcopyproblock(node.getrightchildren(),leafresult); 1094 | targetnode.addrightchildren(righttargetnode); 1095 | righttargetnode.addparents(targetnode); 1096 | return targetnode; 1097 | -------------------------------------------------------------------------------- /rex/bin2ir3.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import angr 4 | 5 | import re 6 | 7 | import copy 8 | import magic 9 | 10 | import binascii 11 | import time 12 | 13 | from problock import * 14 | starttime = ""; 15 | def _get_filetype(data,mime=True): 16 | return magic.from_file(data,mime); 17 | 18 | def filenameformat(filename): 19 | result = filename; 20 | result = result.replace("(","\\("); 21 | result = result.replace(")","\\)"); 22 | return result; 23 | 24 | def getdir(filename): 25 | result = ""; 26 | if not filename.find("/") == -1: 27 | result = filename[0:filename.rindex("/")]; 28 | else: 29 | pass; 30 | return result; 31 | 32 | def getname(filename): 33 | result = ""; 34 | if not filename.find("/") == -1: 35 | result = filename[filename.rindex("/") + 1:len(filename)]; 36 | return result; 37 | 38 | def getidbfilename(filename,posfix): 39 | dirname = getdir(filename); 40 | name = getname(filename); 41 | if not name.find(".") == -1: 42 | name = name[0:name.rindex(".")] + posfix; 43 | else: 44 | name += posfix; 45 | result = dirname + "/" + name; 46 | return result; 47 | 48 | 49 | def rmtmpfile(filename): 50 | filename = filenameformat(filename); 51 | idbfilename = getidbfilename(filename,".idb"); 52 | asmfilename = getidbfilename(filename,".asm"); 53 | os.remove(idbfilename); 54 | os.remove(asmfilename); 55 | 56 | 57 | def idarun(filename, tmpname): 58 | filename = filenameformat(filename); 59 | idbfilename = getidbfilename(filename,".idb"); 60 | tmpname += "idcom"; 61 | print("$HOME/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/idaq -B " + filename); 62 | os.system("$HOME/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/idaq -B " + filename); 63 | print("$HOME/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/idaq -S\"/media/vezir/b2552981-cae5-4a83-9f27-2d07beede43e/CRYPTOREX/idascript/bin2iridc.idc " + tmpname + "\" " + idbfilename); 64 | os.system("$HOME/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/IDA_Pro_v6.4_\(Linux\)_and_Hex-Rays_Decompiler_\(ARM\)/idaq -S\"/media/vezir/b2552981-cae5-4a83-9f27-2d07beede43e/CRYPTOREX/idascript/bin2iridc.idc " + tmpname + "\" " + idbfilename); 65 | rmtmpfile(filename); 66 | 67 | class FILETYPE: 68 | Vxexec = 1, 69 | Vlibobj = 2 70 | 71 | ARCHD=["DCD","DCB","DC",".ascii",".word"]; 72 | 73 | def binlcominfo(filename): 74 | #result 75 | binfile = ""; 76 | functionmap = functioncontainer(); 77 | allfunction = list(); 78 | allfunctionname = dict(); 79 | lcom = dict(); 80 | pltstype = dict(); 81 | rodatatype = dict(); 82 | datatype = dict(); 83 | functiondata = dict(); 84 | functionsp = dict(); 85 | innerfunctions = dict(); 86 | externfunctions = dict(); 87 | alldata = dict(); 88 | externfuncset = set(); 89 | 90 | #flag 91 | binfileflag = True; 92 | allfunctionflag = False; 93 | lcomflag = False; 94 | pltflag = False; 95 | rodataflag = False; 96 | dataflag = False; 97 | functiondataflag = False; 98 | 99 | rfd = open(filename,"r"); 100 | offset = 0; 101 | resulttype = ""; 102 | while 1: 103 | line = rfd.readline().strip(); 104 | if not line: 105 | break; 106 | if line == "all function:": 107 | binfileflag = False; 108 | allfunctionflag = True; 109 | lcomflag = False; 110 | pltflag = False; 111 | rodataflag = False; 112 | dataflag = False; 113 | functiondataflag = False; 114 | 115 | continue; 116 | if line == "lcom": 117 | binfileflag = False; 118 | allfunctionflag = False; 119 | lcomflag = True; 120 | pltflag = False; 121 | rodataflag = False; 122 | dataflag = False; 123 | functiondataflag = False; 124 | 125 | continue; 126 | if line == "pltfunctiontype": 127 | binfileflag = False; 128 | allfunctionflag = False; 129 | lcomflag = False; 130 | pltflag = True; 131 | rodataflag = False; 132 | dataflag = False; 133 | functiondataflag = False; 134 | 135 | continue; 136 | if line == ".rodata": 137 | binfileflag = False; 138 | allfunctionflag = False; 139 | lcomflag = False; 140 | pltflag = False; 141 | rodataflag = True; 142 | dataflag = False; 143 | functiondataflag = False; 144 | 145 | continue; 146 | if line == ".data": 147 | binfileflag = False; 148 | allfunctionflag = False; 149 | lcomflag = False; 150 | pltflag = False; 151 | rodataflag = False; 152 | dataflag = True; 153 | functiondataflag = False; 154 | 155 | continue; 156 | if line == "functionenddata": 157 | binfileflag = False; 158 | allfunctionflag = False; 159 | lcomflag = False; 160 | pltflag = False; 161 | rodataflag = False; 162 | dataflag = False; 163 | functiondataflag = True; 164 | 165 | continue; 166 | 167 | if(binfileflag): 168 | binfile = line; 169 | resulttype,offset = execorlib(binfile); 170 | elif(allfunctionflag): 171 | field = line.split("\t"); 172 | if not (len(field) == 2 or len(field) == 3): 173 | continue; 174 | funcaddr = int(field[0],16) + offset; 175 | allfunction.append(funcaddr); 176 | beginsp = field[1].split(":"); 177 | if len(beginsp) == 2: 178 | functionsp[int(field[0],16) + offset] = beginsp[1].strip(); 179 | innerfunctions[beginsp[0]] = int(field[0],16) + offset; 180 | tmpfunction = function(); 181 | funcn = beginsp[0].strip(); 182 | tmpfunction.setfunctionname(funcn); 183 | allfunctionname[funcaddr]=funcn; 184 | tmpfunction.addfunctionaddr(int(field[0],16)+offset); 185 | tmpfunction.setfunctiontype(FUNCTIONTYPE.inner); 186 | functionmap.addfunction(tmpfunction); 187 | elif(lcomflag): 188 | field = re.split("\s+",line); 189 | #print(field); 190 | if not len(field) == 2: 191 | continue; 192 | lcom[int(field[0],16)+offset] = field[1]; 193 | elif(pltflag): 194 | field = line.split("\t"); 195 | if not (len(field) == 2 or len(field) == 3): 196 | continue; 197 | tmp = ""; 198 | tmpl = list(); 199 | tmpfunction = function(); 200 | functionname = field[1].strip(); 201 | if functionname.startswith("j_") and not functionmap.getfunction(functionname[0+len("j_"):len(functionname)]) == None: 202 | tmpfunction = functionmap.getfunction(functionname[0+len("j_"):len(functionname)]); 203 | tmpfunction.addfunctionaddr(int(field[0],16) + offset); 204 | functionmap.addfunctionaddr(tmpfunction.getfunctionname(),int(field[0],16) + offset); 205 | continue; 206 | else: 207 | tmpfunction.setfunctiontype(FUNCTIONTYPE.extern); 208 | tmpfunction.addfunctionaddr(int(field[0],16) + offset); 209 | externfuncset.add(field[1].strip()); 210 | tmpfunction.setfunctionname(field[1].strip()); 211 | if len(field) == 2: 212 | tmp = [field[1],tmpl]; 213 | elif len(field) == 3: 214 | tmpl = re.split("[(),]",field[2]); 215 | for tmpli in range(0,len(tmpl)): 216 | tmpl[tmpli] = tmpl[tmpli].strip(); 217 | if tmpli == 0: 218 | tmpfunction.setreturntype(tmpl[tmpli].strip()); 219 | #print(functionname); 220 | #print("return type"); 221 | #print(tmpl[tmpli].strip()); 222 | else: 223 | tmpfunction.addarg(tmpl[tmpli].strip()); 224 | tmp = [field[1],tmpl]; 225 | externfunctions[field[1]] = int(field[0],16) + offset; 226 | pltstype[int(field[0],16) + offset] = tmp; 227 | functionmap.addfunction(tmpfunction); 228 | elif(rodataflag): 229 | field = line.split("\t"); 230 | if not len(field) == 2: 231 | continue; 232 | rodatatype[int(field[0],16) + offset] = field[1]; 233 | for aitem in ARCHD: 234 | if field[1].startswith(aitem) and not field[1].find(" ") == -1: 235 | blanklocat = field[1].find(" "); 236 | alldata[int(field[0],16) + offset] = field[1][blanklocat:len(field[1])].strip(); 237 | break; 238 | elif field[1].startswith(aitem): 239 | alldata[int(field[0],16) + offset] = field[1][len(aitem):len(field[1])].strip(); 240 | break; 241 | elif(dataflag): 242 | field = line.split("\t"); 243 | if not len(field) == 2: 244 | continue; 245 | datatype[int(field[0],16) + offset] = field[1]; 246 | for aitem in ARCHD: 247 | if field[1].startswith(aitem) and not field[1].find(" ") == -1: 248 | blanklocat = field[1].find(" "); 249 | alldata[int(field[0],16) + offset] = field[1][blanklocat:len(field[1])].strip(); 250 | break; 251 | elif field[1].startswith(aitem): 252 | alldata[int(field[0],16) + offset] = field[1][len(aitem):len(field[1])].strip(); 253 | break; 254 | elif(functiondataflag): 255 | field = line.split("\t"); 256 | if not len(field) == 2: 257 | continue; 258 | tmpfield1 = field[1][field[1].find(" ") + 1:len(field[1])]; 259 | #print(tmpfield1); 260 | if not field[1].startswith("DC") and field[1].isdigit(): 261 | functiondata[int(field[0],16) + offset] = int(tmpfield1) + offset; 262 | alldata[int(field[0],16) + offset] = int(tmpfield1) + offset; 263 | else: 264 | functiondata[int(field[0],16) + offset] = tmpfield1; 265 | alldata[int(field[0],16) + offset] = tmpfield1; 266 | rfd.close(); 267 | return binfile,allfunction,allfunctionname,lcom,pltstype,rodatatype,datatype,functiondata,functionsp,innerfunctions,externfunctions,functionmap,alldata,externfuncset; 268 | 269 | externfunctiondic = dict(); 270 | 271 | def nmfile(sofile): 272 | result = set(); 273 | sofile =filenameformat(sofile); 274 | filetype = _get_filetype(sofile); 275 | if not filetype == b"application/x-sharedlib": 276 | return result; 277 | output = os.popen("nm -D " + sofile); 278 | allline = output.read().split("\n"); 279 | for line in allline: 280 | field = line.split(" "); 281 | if not len(field) == 3 or not field[1] == "T": 282 | continue; 283 | result.add(field[2]); 284 | return result; 285 | 286 | nextblocktime = 0; 287 | 288 | 289 | def constructmycfg(node,proj,functionmap,lcom,mycfg,addrset,pathnode,test,bpspoffset): 290 | if not node.beginaddr == 0: 291 | pathnode.add(node.beginaddr); 292 | #print("construct0x%X"%node.beginaddr); 293 | #print(node.beginaddr); 294 | global nextblocktime; 295 | testa = time.time(); 296 | bl = node.getnextblockaddr(bpspoffset); 297 | testb = time.time(); 298 | nextblocktime += (testb - testa); 299 | resultleafnode=set(); 300 | rightresultleafset=set(); 301 | callset = set(); 302 | for bitem in bl: 303 | nextaddr = None; 304 | nextnode = None; 305 | tmpleaf = set(); 306 | b=bitem[0]; 307 | slide=bitem[1]; 308 | f=functionmap.getfunction(b); 309 | if not f == None: 310 | if f.getfunctiontype() == FUNCTIONTYPE.inner: 311 | nextaddr = f.getfunctionaddr()[0]; 312 | else: 313 | nextnode = problock(); 314 | nextnode.addexternflag(); 315 | nextnode.addexternfun(f.getfunctionname()); 316 | for a in f.getarg(): 317 | nextnode.addexternfunarg(a); 318 | if not f.getfunctionname() in externfunctiondic: 319 | externfunctiondic[f.getfunctionname()] = list(); 320 | externfunctiondic[f.getfunctionname()].append(nextnode); 321 | elif not b.isdigit(): 322 | continue; 323 | else: 324 | nextaddr = int(b); 325 | 326 | if (not nextaddr == None) and (not nextaddr in addrset): 327 | continue 328 | elif nextnode == None and nextaddr == None: 329 | continue; 330 | elif nextnode == None and (not nextaddr == None):#inner 331 | block = proj.factory.block(nextaddr); 332 | irsb = block.vex; 333 | nextnode = problock(irsb,lcom); 334 | if nextnode.beginaddr in pathnode: 335 | continue; 336 | if (not nextaddr == None) and (not nextaddr == 0) and (nextaddr in mycfg): 337 | nextnode = mycfg[nextaddr][0]; 338 | tmpleaf = mycfg[nextaddr][1]; 339 | else: 340 | global starttime; 341 | nowtime = time.time(); 342 | if int(nowtime - starttime) / 60 <= 5: 343 | nextnode,tmpleaf = constructmycfg(nextnode,proj,functionmap,lcom,mycfg,addrset,copy.copy(pathnode),test+1,node.getbpspoffset()); 344 | mycfg[nextaddr] = [nextnode,tmpleaf]; 345 | resultleafnode=resultleafnode.union(tmpleaf); 346 | if slide == CHILDRENSIZE.Vexit: 347 | slideflag,locat = node.addleftchildren(nextnode); 348 | nextnode.addparents([node,slideflag,locat]); 349 | elif slide == CHILDRENSIZE.Vnext: 350 | slideflag,locat = node.addrightchildren(nextnode); 351 | nextnode.addparents([node,slideflag,locat]); 352 | elif slide == CHILDRENSIZE.Vlr: 353 | if nextaddr in callset: 354 | continue; 355 | slideflag,locat = node.addrightchildren(nextnode); 356 | nextnode.addparents([node,slideflag,locat]); 357 | if (not nextaddr == None) and (not nextaddr == 0): 358 | callset.add(nextaddr); 359 | if node.getleftchildren() == None and node.getrightchildren() == None: 360 | resultleafnode.add(node); 361 | return node,resultleafnode; 362 | 363 | def dfspp(node,time,s=""): 364 | msg = ""; 365 | for i in range(0,time): 366 | msg += " "; 367 | msg += str(time) + " " + s + " "; 368 | msg += node.getmetadata(); 369 | for pnode in node.getparents(): 370 | msg += " 0x%X "%pnode[0].beginaddr; 371 | print(msg); 372 | for cnode in node.getleftchildren(): 373 | dfspp(cnode,time+1); 374 | for cnode in node.getrightchildren(): 375 | dfspp(cnode,time+1); 376 | 377 | def execorlib(filename): 378 | filetype = _get_filetype(filename); 379 | resulttype = ""; 380 | if any(s in [filetype] for s in [b"application/x-executable"]): 381 | #print("x-ex"); 382 | wfiletype = "x-ex\n"; 383 | offset = 0; 384 | resulttype = FILETYPE.Vxexec; 385 | elif any(s in [filetype] for s in [b"application/x-sharedlib"]): 386 | #print("x-obj"); 387 | wfiletype = "x-obj\n"; 388 | offset = 0x400000; 389 | resulttype = FILETYPE.Vlibobj; 390 | return resulttype,offset; 391 | 392 | def execfunction(): 393 | functionfilename = "execfunction" 394 | functionfd = open(functionfilename,"r"); 395 | funcnameset = set(); 396 | funcdetail = dict(); 397 | while True: 398 | line = functionfd.readline().strip(); 399 | if not line: 400 | break; 401 | if not len(line) == 0 and line[0] == "#": 402 | continue; 403 | if len(line) == 0: 404 | continue; 405 | field = line.split("\t"); 406 | if not len(field) == 2: 407 | continue; 408 | funcprototype = re.split("[(),]",field[0].strip()); 409 | if len(funcprototype) == 0: 410 | continue; 411 | funcheader = funcprototype[0].split(" "); 412 | if not len(funcheader) == 2: 413 | continue; 414 | if funcheader[1][0] == "*": 415 | funcheader[1] = funcheader[1][1:len(funcheader[1])]; 416 | funcheader[0] += "*"; 417 | funcnameset.add(funcheader[1]); 418 | tfop = funcop(); 419 | tfop.setfunctionname(funcheader[1]); 420 | tfop.setreturntype(funcheader[0]); 421 | topfield = field[1].split(" "); 422 | for f in topfield: 423 | infodetailfield = f.split(":"); 424 | if not len(infodetailfield) == 3: 425 | continue; 426 | if infodetailfield[0].strip() == "dest": 427 | tfop.setfuncdest(int(infodetailfield[1])); 428 | if infodetailfield[2] == "string": 429 | tfop.setdesttype(FARGTYPE.Vstring); 430 | elif infodetailfield[2] == "int": 431 | tfop.setdesttype(FARGTYPE.Vint); 432 | elif infodetailfield[0].strip() == "src": 433 | tfop.setfuncsrc(int(infodetailfield[1])); 434 | if infodetailfield[2] == "string": 435 | tfop.setsrctype(FARGTYPE.Vstring); 436 | elif infodetailfield[2] == "int": 437 | tfop.setsrctype(FARGTYPE.Vint); 438 | elif infodetailfield[0].strip() == "len": 439 | tfop.setfunclen(int(infodetailfield[1])); 440 | funcdetail[funcheader[1]] = tfop; 441 | functionfd.close(); 442 | return funcnameset,funcdetail; 443 | 444 | 445 | 446 | def rulematch(): 447 | rulefilename = "/media/vezir/b2552981-cae5-4a83-9f27-2d07beede43e/CRYPTOREX/rex/misuseprofile" 448 | print(rulefilename); 449 | rulefd = open(rulefilename,"r"); 450 | print(rulefd); 451 | print("----------------"); 452 | funcnameset = set(); 453 | funcdetail = dict(); 454 | wfuncdetail = dict(); 455 | ruledesresult = dict(); 456 | wfuncset=set(); 457 | ruledesflag = False; 458 | misusefunctionflag = False; 459 | dependflag = False; 460 | while True: 461 | line = rulefd.readline().strip(); 462 | if not line: 463 | break; 464 | if line == "ruledes:": 465 | ruledesflag = True; 466 | misusefunctionflag = False; 467 | wrongflag = False; 468 | elif line == "misusefunction:": 469 | ruledesflag = False; 470 | misusefunctionflag = True; 471 | wrongflag = False; 472 | elif line == "dependfunc:": 473 | wrongflag = True; 474 | ruledesflag = False; 475 | dependflag = False; 476 | 477 | if misusefunctionflag: 478 | if not len(line) == 0 and line[0] == "#": 479 | continue; 480 | field = line.split("\t"); 481 | if not len(field) == 2: 482 | continue; 483 | funcprototype = re.split("[(),]",field[0].strip()); 484 | if len(funcprototype) == 0: 485 | continue; 486 | funcheader = funcprototype[0].split(" "); 487 | if not len(funcheader) == 2: 488 | continue; 489 | if funcheader[1][0] == "*": 490 | funcheader[1] = funcheader[1][1:len(funcheader[1])]; 491 | funcheader[0] += "*"; 492 | funcnameset.add(funcheader[1]); 493 | tmpfunction=function(); 494 | tmpfunction.setfunctionname(funcheader[1]); 495 | tmpfunction.setreturntype(funcheader[0]); 496 | for i in range(1,len(funcprototype)): 497 | if funcprototype[i] == "": 498 | continue; 499 | tmpfunction.addarg(funcprototype[i].strip()); 500 | farglocat = field[1].split(";"); 501 | for glocatg in farglocat: 502 | glocat = glocatg.split(":"); 503 | if not len(glocat) == 4: 504 | continue; 505 | if glocat[1].strip() == "string": 506 | tmpfunction.addfarg([int(glocat[0]),FARGTYPE.Vstring]); 507 | elif glocat[1].strip() == "int": 508 | tmpfunction.addfarg([int(glocat[0]),FARGTYPE.Vint]); 509 | elif glocat[1].strip() == "len": 510 | tmpfunction.addfarg([int(glocat[0]),FARGTYPE.Vlen]); 511 | elif glocat[1].strip() == "none": 512 | tmpfunction.addfarg([int(glocat[0]),FARGTYPE.Vnone]); 513 | tmpfunction.addrule(int(glocat[2])); 514 | tmpfunction.addruledes(ruledesresult[int(glocat[2])]); 515 | tmpfunction.addlimit(glocat[3]); 516 | funcdetail[funcheader[1]] = tmpfunction; 517 | elif ruledesflag: 518 | if not len(line) == 0 and line[0] == "#": 519 | continue; 520 | field = line.split("\t"); 521 | if not len(field) == 2: 522 | continue; 523 | ruledesresult[int(field[0])] = field[1]; 524 | elif dependflag: 525 | if not len(line) == 0 and line[0] == "#": 526 | continue; 527 | functionfield = line.split("->"); 528 | if not len(field) == 2: 529 | continue; 530 | funcprototype = re.split("[(),]",field[0].strip()); 531 | if len(funcprototype) == 0: 532 | continue; 533 | funcheader = funcprototype[0].split(" "); 534 | if not len(funcheader) == 2: 535 | continue; 536 | if funcheader[1][0] == "*": 537 | funcheader[1] = funcheader[1][1:len(funcheader[1])]; 538 | funcheader[0] += "*"; 539 | wfuncset.add(funcheader[1]); 540 | tmpfunction=function(); 541 | tmpfunction.setfunctionname(funcheader[1]); 542 | tmpfunction.setreturntype(funcheader[0]); 543 | for i in range(1,len(funcprototype)): 544 | if funcprototype[i] == "": 545 | continue; 546 | tmpfunction.addarg(funcprototype[i].strip()); 547 | farglocat = field[1].split(";"); 548 | for glocatg in farglocat: 549 | glocat = glocatg.split(":"); 550 | if not len(glocat) == 4: 551 | continue; 552 | if glocat[1].strip() == "string": 553 | tmpfunction.addfarg([int(glocat[0]),FARGTYPE.Vstring]); 554 | elif glocat[1].strip() == "int": 555 | tmpfunction.addfarg([int(glocat[0]),FARGTYPE.Vint]); 556 | tmpfunction.addrule(int(glocat[2])); 557 | tmpfunction.addruledes(ruledesresult[int(glocat[2])]); 558 | tmpfunction.addlimit(glocat[3]); 559 | wfuncdetail[funcheader[1]] = tmpfunction; 560 | 561 | rulefd.close(); 562 | return funcnameset,funcdetail,ruledesresult,wfuncset,wfuncdetail; 563 | 564 | '''def finishfuncdetail(function,pnode): 565 | function.clearfunctionaarg(); 566 | if len(function.getarg()) < 4: 567 | comlist = pnode.getcomarglist(); 568 | for i in range(0,len(function.getarg())): 569 | function.addfunctionaarg([comlist[i],ARGTYPE.Voffset]); 570 | else: 571 | aargnum = len(function.getarg()); 572 | comlist = pnode.getcomarglist(); 573 | for i in range(0,4): 574 | function.addfunctionaarg([comlist[i],ARGTYPE.Voffset]); 575 | for i in range(4,aargnum): 576 | function.addfunctionaarg([i-4,ARGTYPE.Vstackv]); 577 | ''' 578 | 579 | def reversedfs(node,time,prefix=""): 580 | msg = prefix; 581 | msg += node.getmetadata() + " "; 582 | for pnode in node.getparents(): 583 | reversedfs(pnode[0],time+1,msg); 584 | if len(node.getparents()) == 0: 585 | print(msg); 586 | 587 | 588 | archdataformat = ["word_","dword_","unk_","byte_"]; 589 | 590 | def hex2str(hexstr): 591 | datad = hexstr; 592 | fdata = ""; 593 | if datad.lower().startswith("0x"): 594 | dfield = datad.split(","); 595 | for fditem in dfield: 596 | tmpdata = fditem.strip(); 597 | if tmpdata.lower().startswith("0x"): 598 | tmpdata = tmpdata[2:]; 599 | if len(tmpdata) % 2 == 1: 600 | tmpdata = "0" + tmpdata; 601 | print(tmpdata); 602 | fdata += binascii.a2b_hex(tmpdata)[::-1]; 603 | else: 604 | fdata = datad; 605 | else: 606 | fdata = hexstr; 607 | return fdata; 608 | 609 | 610 | def reversetracedfs(nodeset,tinfo,offset,alldata,soffset,depth,execfuncdetail,allfn,middlefunc,ef,detailreport,wfuncsetreturn,pathroad): 611 | node = nodeset[0]; 612 | irsb = node.getirsb(); 613 | takeaction = False; 614 | actionv = list(); 615 | actiont = list(); 616 | ntinfo = traceinfo(); 617 | slidechild = nodeset[1]; 618 | childlocat = nodeset[2]; 619 | '''msg = ""; 620 | for i in range(0,time): 621 | msg +=" " 622 | msg += "0x%X"%node.beginaddr; 623 | print(msg);''' 624 | global starttime; 625 | nowtime = time.time(); 626 | #print(int(nowtime-starttime)); 627 | if int(nowtime - starttime)/60 >= 2: 628 | return; 629 | if node.beginaddr in pathroad: 630 | return; 631 | else: 632 | pathroad.add(node.beginaddr); 633 | for indexi in range(0,childlocat): 634 | if slidechild == CHILRENSLIDE.Vleft: 635 | childpro = node.getleftchildren()[indexi]; 636 | if childpro.externflag() and childpro.getexternfun() in execfuncdetail: 637 | execfunname = childpro.getexternfun(); 638 | src = execfuncdetail[execfunname].getfuncsrc() - 1; 639 | dest = execfuncdetail[execfunname].getfuncdest() - 1; 640 | destv = 0; 641 | destvtype = 0; 642 | if dest < 4: 643 | destv = node.getcomarglist()[dest]; 644 | destvtype = ARGTYPE.Voffset; 645 | meta = ""; 646 | vargtype = execfuncdetail[execfunname].getsrctype(); 647 | ntinfo.addalllist(destv,destvtype,meta,vargtype,node.beginaddr,-1,""); 648 | else: 649 | destv = dest - 4; 650 | destvtype = ARGTYPE.Vstackv; 651 | meta = ""; 652 | vargtype = execfuncdetail[execfunname].getsrctype(); 653 | ntinfo.addalllist(destv,destvtype,meta,vargtype,node.beginaddr,-1,""); 654 | if src < 4: 655 | v = node.getcomarglist()[src]; 656 | vtype = ARGTYPE.Voffset; 657 | vargtype = execfuncdetail[execfunname].getsrctype(); 658 | ntinfo.keyadddup(destv,destvtype,v,vtype); 659 | else: 660 | v = src - 4; 661 | vtype = ARGTYPE.Vstackv; 662 | vargtype = execfuncdetail[execfunname].getsrctype(); 663 | ntinfo.keyadddup(destv,destvtype,v,vtype); 664 | elif childpro.externflag(): 665 | for index in range(0,node.unfixedarglen()): 666 | offset = node.getunfixedarg(index); 667 | if tinfo.keyin(offset,ARGTYPE.Voffset): 668 | tinfo.setntrace(offset,ARGTYPE.Voffset); 669 | #if childpro.externflag() and childpro.getexternfun() in wfuncsetreturn: 670 | # print(childpro.getexternfun()); 671 | 672 | elif slidechild == CHILRENSLIDE.Vright: 673 | childpro = node.getrightchildren()[indexi]; 674 | if childpro.externflag() and childpro.getexternfun() in execfuncdetail: 675 | execfunname = childpro.getexternfun(); 676 | src = execfuncdetail[execfunname].getfuncsrc() - 1; 677 | dest = execfuncdetail[execfunname].getfuncdest() - 1; 678 | destv = 0; 679 | destvtype = 0; 680 | if dest < 4: 681 | destv = node.getcomarglist()[dest]; 682 | destvtype = ARGTYPE.Voffset; 683 | meta = ""; 684 | vargtype = execfuncdetail[execfunname].getsrctype(); 685 | ntinfo.addalllist(destv,destvtype,meta,vargtype,node.beginaddr,-1,""); 686 | else: 687 | destv = dest - 4; 688 | destvtype = ARGTYPE.Vstackv; 689 | meta = ""; 690 | vargtype = execfuncdetail[execfunname].getsrctype(); 691 | ntinfo.addalllist(destv,destvtype,meta,vargtype,node.beginaddr,-1,""); 692 | if src < 4: 693 | v = node.getcomarglist()[src]; 694 | vtype = ARGTYPE.Voffset; 695 | vargtype = execfuncdetail[execfunname].getsrctype(); 696 | ntinfo.keyadddup(destv,destvtype,v,vtype); 697 | else: 698 | v = src - 4; 699 | vtype = ARGTYPE.Vstackv; 700 | vargtype = execfuncdetail[execfunname].getsrctype(); 701 | ntinfo.keyadddup(destv,destvtype,v,vtype); 702 | elif childpro.externflag(): 703 | for index in range(0,node.unfixedarglen()): 704 | offset = node.getunfixedarg(index); 705 | if tinfo.keyin(offset,ARGTYPE.Voffset): 706 | tinfo.setntrace(offset,ARGTYPE.Voffset); 707 | for indexvt in range(0,len(tinfo.vtypel)): 708 | if not tinfo.vtypel[indexvt] == ARGTYPE.Vstackv: 709 | continue; 710 | elif tinfo.vl[indexvt]+soffset < 0: 711 | tinfo.setntrace(tinfo.vl[indexvt],tinfo.vtypel[indexvt]); 712 | elif tinfo.vl[indexvt] + soffset >= len(node.stack): 713 | continue; 714 | elif node.stack[tinfo.vl[indexvt] + soffset][1] == ARGTYPE.Vtmp: 715 | if str(node.stack[tinfo.vl[indexvt] + soffset][0]) + " " + str(node.stack[tinfo.vl[indexvt] + soffset][1]) in node.sprelate: 716 | for spitem in node.sprelate: 717 | if node.sprelate[str(node.stack[tinfo.vl[indexvt] + soffset][0]) + " " + str(node.stack[tinfo.vl[indexvt] + soffset][1])] == node.sprelate[spitem] and not str(node.stack[tinfo.vl[indexvt] + soffset][0]) + " " + str(node.stack[tinfo.vl[indexvt] + soffset][1]) == spitem: 718 | field = spitem.split(" "); 719 | tinfo.keyadddup(tinfo.vl[indexvt],tinfo.vtypel[indexvt],int(field[0]),field[1]); 720 | tinfo.keyupdate(tinfo.vl[indexvt],tinfo.vtypel[indexvt],node.stack[tinfo.vl[indexvt] + soffset][0],node.stack[tinfo.vl[indexvt] + soffset][1]); 721 | elif node.stack[tinfo.vl[indexvt] + soffset][1] == ARGTYPE.Vconst: 722 | if tinfo.getargtype(tinfo.vl[indexvt],tinfo.vtypel[indexvt]) == FARGTYPE.Vint: 723 | tinfo.setfresult(tinfo.vl[indexvt],tinfo.vtypel[indexvt],node.stack[tinfo.vl[indexvt] + soffset][0]); 724 | tinfo.setntrace(tinfo.vl[indexvt],tinfo.vtypel[indexvt]); 725 | elif tinfo.getargtype(tinfo.vl[indexvt],tinfo.vtypel[indexvt]) == FARGTYPE.Vstring: 726 | if node.stack[tinfo.vl[indexvt] + soffset][0] in alldata and isinstance(alldata[node.stack[tinfo.vl[indexvt] + soffset][0]],int) and alldata[node.stack[tinfo.vl[indexvt] + soffset][0]] in alldata: 727 | fresult = hex2str(alldata[alldata[node.stack[tinfo.vl[indexvt] + soffset][0]]]); 728 | tinfo.setfresult(tinfo.vl[indexvt],tinfo.vtypel[indexvt],fresult); 729 | tinfo.setntrace(tinfo.vl[indexvt],tinfo.vtypel[indexvt]); 730 | elif node.stack[tinfo.vl[indexvt] + soffset][0] in alldata and not isinstance(alldata[node.stack[tinfo.vl[indexvt] + soffset][0]],int): 731 | fresult = hex2str(alldata[node.stack[tinfo.vl[indexvt] + soffset][0]]); 732 | tinfo.setfresult(tinfo.vl[indexvt],tinfo.vtypel[indexvt],fresult); 733 | tinfo.setntrace(tinfo.vl[indexvt],tinfo.vtypel[indexvt]); 734 | else: 735 | tinfo.keyupdate(tinfo.vl[indexvt],tinfo.vtypel[indexvt],node.stack[tinfo.vl[indexvt] + soffset][0],node.stack[tinfo.vl[indexvt] + soffset][1]); 736 | elif node.stack[tinfo.vl[indexvt] + soffset][1] == ARGTYPE.Voffset: 737 | if str(node.stack[tinfo.vl[indexvt] + soffset][0]) + " " + str(node.stack[tinfo.vl[indexvt] + soffset][1]) in node.sprelate: 738 | for spitem in node.sprelate: 739 | if node.sprelate[str(node.stack[tinfo.vl[indexvt] + soffset][0]) + " " + str(node.stack[tinfo.vl[indexvt] + soffset][1])] == node.sprelate[spitem] and not str(node.stack[tinfo.vl[indexvt] + soffset][0]) + " " + str(node.stack[tinfo.vl[indexvt] + soffset][1]) == spitem: 740 | field = spitem.split(" "); 741 | tinfo.keyadddup(tinfo.vl[indexvt],tinfo.vtypel[indexvt],int(field[0]),field[1]); 742 | tinfo.keyupdate(tinfo.vl[indexvt],tinfo.vtypel[indexvt],node.stack[tinfo.vl[indexvt] + soffset][0],node.stack[tinfo.vl[indexvt] + soffset][1]); 743 | #if node.beginaddr == 0x4008d8 or node.beginaddr == 0x10550: 744 | # print("bbegin0x%X"%node.beginaddr); 745 | # tinfo.listdebugpp(); 746 | # print(node.stack); 747 | # print(node.sprelate); 748 | if not ntinfo.ntlen() == 0: 749 | for sitem in reversed(irsb.statements): 750 | if sitem.tag == "Ist_IMark": 751 | if takeaction: 752 | takeaction = False; 753 | for i in range(0,len(actionv)): 754 | ntinfo.setfaddr(actionv[i],actiont[i],sitem.addr); 755 | comment = ""; 756 | dataaddr = 0x0; 757 | if not ntinfo.gettrace(actionv[i],actiont[i]): 758 | continue; 759 | if sitem.addr in node.lcom: 760 | comment = node.lcom[sitem.addr]; 761 | else: 762 | continue; 763 | #print(comment); 764 | if ntinfo.getargtype(actionv[i],actiont[i]) == FARGTYPE.Vstring and comment[0] == "\"" and comment[len(comment) - 1] == "\"": 765 | ntinfo.setfresult(actionv[i],actiont[i],node.lcom[sitem.addr]); 766 | ntinfo.setntrace(actionv[i],actiont[i]); 767 | elif ntinfo.getargtype(actionv[i],actiont[i]) == FARGTYPE.Vstring and comment[0] == "\'" and comment[len(comment) - 1] == "\'": 768 | ntinfo.setfresult(actionv[i],actiont[i],node.lcom[sitem.addr]); 769 | ntinfo.setntrace(actionv[i],actiont[i]); 770 | elif ntinfo.getargtype(actionv[i],actiont[i]) == FARGTYPE.Vstring: 771 | for dfitem in archdataformat: 772 | if comment.lower().startswith(dfitem): 773 | dataaddr = int(comment.lower()[len(dfitem):len(comment)],16) + offset; 774 | if dataaddr in alldata: 775 | nprint = True; 776 | datad = alldata[dataaddr]; 777 | fdata = hex2str(datad); 778 | ntinfo.setfresult(actionv[i],actiont[i],fdata); 779 | ntinfo.setntrace(actionv[i],actiont[i]); 780 | break; 781 | #ntinfo.setntrace(actionv[i],actiont[i]); 782 | actionv = []; 783 | actiont = []; 784 | elif sitem.tag == "Ist_Exit": 785 | continue; 786 | elif sitem.tag == "Ist_Put": 787 | if ntinfo.keyin(sitem.offset,ARGTYPE.Voffset) and ntinfo.gettrace(sitem.offset,ARGTYPE.Voffset): 788 | eitem = sitem.data; 789 | if eitem.tag == "Iex_Unop": 790 | pass; 791 | elif eitem.tag == "Iex_RdTmp": 792 | takeaction = True; 793 | ntinfo.keyupdate(sitem.offset,ARGTYPE.Voffset,eitem.tmp,ARGTYPE.Vtmp); 794 | actionv.append(eitem.tmp); 795 | actiont.append(ARGTYPE.Vtmp); 796 | elif eitem.tag == "Iex_Load": 797 | pass; 798 | elif eitem.tag == "Iex_Const": 799 | if ntinfo.getargtype(sitem.offset,ARGTYPE.Voffset) == FARGTYPE.Vint: 800 | takeaction = True; 801 | ntinfo.setfresult(sitem.offset,ARGTYPE.Voffset,eitem.con.value); 802 | ntinfo.setntrace(sitem.offset,ARGTYPE.Voffset); 803 | actionv.append(sitem.offset); 804 | actiont.append(ARGTYPE.Voffset); 805 | elif ntinfo.getargtype(sitem.offset,ARGTYPE.Voffset) == FARGTYPE.Vstring: 806 | takeaction = True; 807 | if eitem.con.value in alldata and isinstance(alldata[eitem.con.value],int)and alldata[eitem.con.value] in alldata: 808 | fresult = hex2str(alldata[alldata[eitem.con.value]]); 809 | ntinfo.setfresult(sitem.offset,ARGTYPE.Voffset,fresult); 810 | ntinfo.setntrace(sitem.offset,ARGTYPE.Voffset); 811 | takeaction = True; 812 | elif eitem.con.value in alldata and not isinstance(alldata[eitem.con.value],int): 813 | fresult = hex2str(alldata[eitem.con.value]); 814 | ntinfo.setfresult(sitem.offset,ARGTYPE.Voffset,fresult); 815 | ntinfo.setntrace(sitem.offset,ARGTYPE.Voffset); 816 | takeaction = True; 817 | else: 818 | takeaction = True; 819 | ntinfo.setfresult(sitem.offset,ARGTYPE.Voffset,eitem.con.value); 820 | ntinfo.setntrace(sitem.offset,ARGTYPE.Voffset); 821 | actionv.append(sitem.offset); 822 | actiont.append(ARGTYPE.Voffset); 823 | elif eitem.tag == "Iex_Binop": 824 | pass; 825 | elif eitem.tag == "Iex_Get": 826 | pass; 827 | elif sitem.tag == "Ist_WrTmp": 828 | if ntinfo.keyin(sitem.tmp,ARGTYPE.Vtmp) and ntinfo.gettrace(sitem.tmp,ARGTYPE.Vtmp): 829 | eitem = sitem.data; 830 | if eitem.tag == "Iex_Unop": 831 | pass; 832 | elif eitem.tag == "Iex_RdTmp": 833 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,eitem.tmp,ARGTYPE.Vtmp); 834 | elif eitem.tag == "Iex_Load": 835 | laddr = eitem.addr; 836 | if ntinfo.getargtype(sitem.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vstring: 837 | if laddr.tag == "Iex_Const" and laddr.con.value in alldata and isinstance(alldata[laddr.con.value],int)and alldata[laddr.con.value] in alldata: 838 | fresult = hex2str(alldata[alldata[laddr.con.value]]); 839 | ntinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 840 | ntinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 841 | takeaction = True; 842 | elif laddr.tag == "Iex_Const" and laddr.con.value in alldata and not isinstance(alldata[laddr.con.value],int): 843 | fresult = hex2str(alldata[laddr.con.value]); 844 | ntinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 845 | ntinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 846 | takeaction = True; 847 | elif laddr.tag == "Iex_RdTmp" and ntinfo.gettrace(sitem.tmp,ARGTYPE.Vtmp): 848 | v = 0; 849 | vtype = ARGTYPE.Vunkown; 850 | if node.instack(laddr.tmp,ARGTYPE.Vtmp): 851 | tmpvstackdata = node.getstackdata(laddr.tmp,ARGTYPE.Vtmp); 852 | v = tmpvstackdata[0]; 853 | vtype = tmpvstackdata[1]; 854 | if vtype == ARGTYPE.Voffset: 855 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 856 | elif vtype == ARGTYPE.Vtmp: 857 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 858 | elif vtype == ARGTYPE.Vconst: 859 | if v in alldata and isinstance(alldata[v],int)and alldata[v] in alldata: 860 | fresult = hex2str(alldata[alldata[v]]); 861 | ntinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 862 | ntinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 863 | takeaction = True; 864 | elif v in alldata and not isinstance(alldata[v],int): 865 | fresult = hex2str(alldata[laddr.con.value]); 866 | ntinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 867 | ntinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 868 | takeaction = True; 869 | elif vtype == ARGTYPE.Vunkown: 870 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,laddr.tmp,ARGTYPE.Vtmp); 871 | actionv.append(laddr.tmp); 872 | actiont.append(ARGTYPE.Vtmp); 873 | elif ntinfo.getargtype(sitem.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vint: 874 | if laddr.tag == "Iex_Const": 875 | ntinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,laddr.con.value); 876 | ntinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 877 | elif laddr.tag == "Iex_RdTmp" and node.instack(laddr.tmp,ARGTYPE.Vtmp): 878 | takeaction = True; 879 | stacklocatinfo = node.getstackdata(laddr.tmp ,ARGTYPE.Vtmp); 880 | v = stacklocatinfo[0]; 881 | vtype = stacklocatinfo[1]; 882 | if vtype == ARGTYPE.Voffset: 883 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Voffset); 884 | elif vtype == ARGTYPE.Vtmp: 885 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Vtmp); 886 | elif vtype == ARGTYPE.Vconst: 887 | ntinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,v); 888 | ntinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 889 | elif laddr.tag == "Iex_RdTmp": 890 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,laddr.tmp,ARGTYPE.Vtmp); 891 | elif eitem.tag == "Iex_Const": 892 | if ntinfo.getargtype(sitem.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vint: 893 | takeaction = True; 894 | ntinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,eitem.con.value); 895 | ntinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 896 | actionv.append(sitem.tmp); 897 | actiont.append(ARGTYPE.Vtmp); 898 | elif eitem.tag == "Iex_Binop": 899 | takeaction = True; 900 | elif eitem.tag == "Iex_Get": 901 | takeaction = True; 902 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,eitem.offset,ARGTYPE.Voffset); 903 | actionv.append(eitem.offset); 904 | actiont.append(ARGTYPE.Voffset); 905 | elif sitem.tag == "Ist_Store": 906 | if sitem.addr.tag == "Iex_Const": 907 | if ntinfo.keyin(sitem.addr.constants[0].value,ARGTYPE.Vconst) and ntinfo.gettrace(sitem.addr.constants[0].value,ARGTYPE.Vconst): 908 | eitem = sitem.data; 909 | if eitem.tag == "Iex_Const": 910 | if ntinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vint: 911 | ntinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,eitem.con.value); 912 | ntinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 913 | takeaction = True; 914 | elif ntinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vstring: 915 | if eitem.con.value in alldata and isinstance(alldata[eitem.con.value],int)and alldata[eitem.con.value] in alldata: 916 | fresult = hex2str(alldata[alldata[eitem.con.value]]); 917 | ntinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 918 | ntinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 919 | takeaction = True; 920 | elif eitem.con.value in alldata and not isinstance(alldata[eitem.con.value],int): 921 | fresult = hex2str(alldata[eitem.con.value]); 922 | ntinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 923 | ntinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 924 | takeaction = True; 925 | else: 926 | ntinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,eitem.con.value,ARGTYPE.Vconst); 927 | actionv.append(eitem.con.value); 928 | actiont.append(ARGTYPE.Vconst); 929 | takeaction = True; 930 | elif eitem.tag == "Iex_RdTmp": 931 | if ntinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vint: 932 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 933 | takeaction = True; 934 | stacklocatinfo = node.getstackdata(eitem.tmp ,ARGTYPE.Vtmp); 935 | v = stacklocatinfo[0]; 936 | vtype = stacklocatinfo[1]; 937 | if vtype == ARGTYPE.Voffset: 938 | ntinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,ARGTYPE.Voffset); 939 | elif vtype == ARGTYPE.Vtmp: 940 | ntinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,ARGTYPE.Vtmp); 941 | elif vtype == ARGTYPE.Vconst: 942 | ntinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,v); 943 | ntinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 944 | elif ntinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vstring: 945 | v = 0; 946 | vtype = ARGTYPE.Vunkown; 947 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 948 | tmpvstackdata = node.getstackdata(eitem.tmp,ARGTYPE.Vtmp); 949 | v = tmpvstackdata[0]; 950 | vtype = tmpvstackdata[1]; 951 | if vtype == ARGTYPE.Voffset: 952 | ntinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,vtype); 953 | elif vtype == ARGTYPE.Vtmp: 954 | ntinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,vtype); 955 | elif vtype == ARGTYPE.Vconst: 956 | if v in alldata and isinstance(alldata[v],int)and alldata[v] in alldata: 957 | fresult = hex2str(alldata[alldata[v]]); 958 | ntinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 959 | ntinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 960 | takeaction = True; 961 | elif v in alldata and not isinstance(alldata[v],int): 962 | fresult = hex2str(alldata[laddr.con.value]); 963 | ntinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 964 | ntinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 965 | takeaction = True; 966 | elif vtype == ARGTYPE.Vunkown: 967 | ntinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,eitem.tmp,ARGTYPE.Vtmp); 968 | actionv.append(eitem.tmp); 969 | actiont.append(ARGTYPE.Vtmp); 970 | takeaction = True; 971 | elif sitem.addr.tag == "Iex_RdTmp": 972 | if ntinfo.keyin(sitem.addr.tmp,ARGTYPE.Vtmp) and ntinfo.gettrace(sitem.addr.tmp,ARGTYPE.Vtmp): 973 | eitem = sitem.data; 974 | if eitem.tag == "Iex_Const": 975 | if ntinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp,ARGTYPE.Vconst) == FARGTYPE.Vint: 976 | ntinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.con.value); 977 | ntinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 978 | takeaction = True; 979 | elif ntinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp,ARGTYPE.Vconst) == FARGTYPE.Vstring: 980 | if eitem.con.value in alldata and isinstance(alldata[eitem.con.value],int)and alldata[eitem.con.value] in alldata: 981 | fresult = hex2str(alldata[alldata[eitem.con.value]]); 982 | ntinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 983 | ntinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp,ARGTYPE.Vconst); 984 | takeaction = True; 985 | elif eitem.con.value in alldata and not isinstance(alldata[eitem.con.value],int): 986 | fresult = hex2str(alldata[eitem.con.value]); 987 | ntinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 988 | ntinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 989 | takeaction = True; 990 | else: 991 | ntinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.con.value,ARGTYPE.Vconst); 992 | actionv.append(eitem.con.value); 993 | actiont.append(ARGTYPE.Vconst); 994 | takeaction = True; 995 | elif eitem.tag == "Iex_RdTmp": 996 | if ntinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vint: 997 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 998 | takeaction = True; 999 | stacklocatinfo = node.getstackdata(eitem.tmp ,ARGTYPE.Vtmp); 1000 | v = stacklocatinfo[0]; 1001 | vtype = stacklocatinfo[1]; 1002 | if vtype == ARGTYPE.Voffset: 1003 | ntinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Voffset); 1004 | elif vtype == ARGTYPE.Vtmp: 1005 | ntinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Vtmp); 1006 | elif vtype == ARGTYPE.Vconst: 1007 | ntinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,v); 1008 | ntinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1009 | elif ntinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vstring: 1010 | v = 0; 1011 | vtype = ARGTYPE.Vunkown; 1012 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 1013 | tmpvstackdata = node.getstackdata(eitem.tmp,ARGTYPE.Vtmp); 1014 | v = tmpvstackdata[0]; 1015 | vtype = tmpvstackdata[1]; 1016 | if vtype == ARGTYPE.Voffset: 1017 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 1018 | elif vtype == ARGTYPE.Vtmp: 1019 | ntinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 1020 | elif vtype == ARGTYPE.Vconst: 1021 | if v in alldata and isinstance(alldata[v],int)and alldata[v] in alldata: 1022 | fresult = hex2str(alldata[alldata[v]]); 1023 | ntinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 1024 | ntinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1025 | takeaction = True; 1026 | elif v in alldata and not isinstance(alldata[v],int): 1027 | fresult = hex2str(alldata[laddr.con.value]); 1028 | ntinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 1029 | ntinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1030 | takeaction = True; 1031 | elif vtype == ARGTYPE.Vunkown: 1032 | ntinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.tmp,ARGTYPE.Vtmp); 1033 | actionv.append(eitem.tmp); 1034 | actiont.append(ARGTYPE.Vtmp); 1035 | ntinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.tmp,ARGTYPE.Vtmp); 1036 | actionv.append(eitem.tmp); 1037 | actiont.append(ARGTYPE.Vtmp); 1038 | takeaction = True; 1039 | #if node.beginaddr == 0x402dd8 or node.beginaddr == 0x10550: 1040 | # print("vbegin0x%X"%node.beginaddr); 1041 | # tinfo.listdebugpp(); 1042 | # print(node.stack); 1043 | # print(node.sprelate); 1044 | for i in range(0,tinfo.alllen()): 1045 | vv = tinfo.getindexvl(i); 1046 | vtypev = tinfo.getindexvtypel(i); 1047 | if ntinfo.keyin(vv,vtypev) and not ntinfo.gettrace(vv,vtypev): 1048 | tinfo.setfresult(vv,vtypev,ntinfo.getfresult(vv,vtypev)); 1049 | tinfo.setfaddr(vv,vtypev,ntinfo.getfaddr(vv,vtypev)); 1050 | tinfo.setntrace(vv,vtypev); 1051 | #if node.beginaddr == 0x402dd8 or node.beginaddr == 0x10550: 1052 | # print("begin0x%X"%node.beginaddr); 1053 | # tinfo.listdebugpp(); 1054 | if not tinfo.ntlen() == 0: 1055 | for sitem in reversed(irsb.statements): 1056 | if sitem.tag == "Ist_IMark": 1057 | #print(takeaction); 1058 | if takeaction: 1059 | #print("0x%X"%sitem.addr); 1060 | #print(actionv); 1061 | #print(actiont); 1062 | takeaction = False; 1063 | for i in range(0,len(actionv)): 1064 | tinfo.setfaddr(actionv[i],actiont[i],sitem.addr); 1065 | comment = ""; 1066 | dataaddr = 0x0; 1067 | if not tinfo.gettrace(actionv[i],actiont[i]): 1068 | continue; 1069 | if sitem.addr in node.lcom: 1070 | comment = node.lcom[sitem.addr]; 1071 | else: 1072 | continue; 1073 | #print(comment); 1074 | if tinfo.getargtype(actionv[i],actiont[i]) == FARGTYPE.Vstring and comment[0] == "\"" and comment[len(comment) - 1] == "\"": 1075 | tinfo.setfresult(actionv[i],actiont[i],node.lcom[sitem.addr]); 1076 | tinfo.setntrace(actionv[i],actiont[i]); 1077 | elif tinfo.getargtype(actionv[i],actiont[i]) == FARGTYPE.Vstring and comment[0] == "\'" and comment[len(comment) - 1] == "\'": 1078 | tinfo.setfresult(actionv[i],actiont[i],node.lcom[sitem.addr]); 1079 | tinfo.setntrace(actionv[i],actiont[i]); 1080 | elif tinfo.getargtype(actionv[i],actiont[i]) == FARGTYPE.Vstring: 1081 | for dfitem in archdataformat: 1082 | if comment.lower().startswith(dfitem): 1083 | dataaddr = int(comment.lower()[len(dfitem):len(comment)],16) + offset; 1084 | if dataaddr in alldata: 1085 | nprint = True; 1086 | datad = alldata[dataaddr]; 1087 | fdata = hex2str(datad); 1088 | tinfo.setfresult(actionv[i],actiont[i],fdata); 1089 | tinfo.setntrace(actionv[i],actiont[i]); 1090 | break; 1091 | #tinfo.setntrace(actionv[i],actiont[i]); 1092 | actionv = []; 1093 | actiont = []; 1094 | elif sitem.tag == "Ist_Exit": 1095 | continue; 1096 | elif sitem.tag == "Ist_Put": 1097 | if tinfo.keyin(sitem.offset,ARGTYPE.Voffset) and tinfo.gettrace(sitem.offset,ARGTYPE.Voffset): 1098 | eitem = sitem.data; 1099 | if eitem.tag == "Iex_Unop": 1100 | pass; 1101 | elif eitem.tag == "Iex_RdTmp": 1102 | takeaction = True; 1103 | tinfo.keyupdate(sitem.offset,ARGTYPE.Voffset,eitem.tmp,ARGTYPE.Vtmp); 1104 | actionv.append(eitem.tmp); 1105 | actiont.append(ARGTYPE.Vtmp); 1106 | elif eitem.tag == "Iex_Load": 1107 | pass; 1108 | elif eitem.tag == "Iex_Const": 1109 | if tinfo.getargtype(sitem.offset,ARGTYPE.Voffset) == FARGTYPE.Vint: 1110 | takeaction = True; 1111 | tinfo.setfresult(sitem.offset,ARGTYPE.Voffset,eitem.con.value); 1112 | tinfo.setntrace(sitem.offset,ARGTYPE.Voffset); 1113 | actionv.append(sitem.offset); 1114 | actiont.append(ARGTYPE.Voffset); 1115 | elif tinfo.getargtype(sitem.offset,ARGTYPE.Voffset) == FARGTYPE.Vstring: 1116 | takeaction = True; 1117 | if eitem.con.value in alldata and isinstance(alldata[eitem.con.value],int)and alldata[eitem.con.value] in alldata: 1118 | fresult = hex2str(alldata[alldata[eitem.con.value]]); 1119 | tinfo.setfresult(sitem.offset,ARGTYPE.Voffset,fresult); 1120 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1121 | takeaction = True; 1122 | elif eitem.con.value in alldata and not isinstance(alldata[eitem.con.value],int): 1123 | fresult = hex2str(alldata[eitem.con.value]); 1124 | tinfo.setfresult(sitem.offset,ARGTYPE.Voffset,fresult); 1125 | tinfo.setntrace(sitem.offset,ARGTYPE.Voffset); 1126 | takeaction = True; 1127 | else: 1128 | takeaction = True; 1129 | tinfo.setfresult(sitem.offset,ARGTYPE.Voffset,eitem.con.value); 1130 | tinfo.setntrace(sitem.offset,ARGTYPE.Voffset); 1131 | actionv.append(sitem.offset); 1132 | actiont.append(ARGTYPE.Voffset); 1133 | elif eitem.tag == "Iex_Binop": 1134 | pass; 1135 | elif eitem.tag == "Iex_Get": 1136 | pass; 1137 | elif sitem.tag == "Ist_WrTmp": 1138 | if tinfo.keyin(sitem.tmp,ARGTYPE.Vtmp) and tinfo.gettrace(sitem.tmp,ARGTYPE.Vtmp): 1139 | eitem = sitem.data; 1140 | if eitem.tag == "Iex_Unop": 1141 | pass; 1142 | elif eitem.tag == "Iex_RdTmp": 1143 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,eitem.tmp,ARGTYPE.Vtmp); 1144 | elif eitem.tag == "Iex_Load": 1145 | laddr = eitem.addr; 1146 | if tinfo.getargtype(sitem.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vstring: 1147 | if laddr.tag == "Iex_Const" and laddr.con.value in alldata and isinstance(alldata[laddr.con.value],int)and alldata[laddr.con.value] in alldata: 1148 | fresult = hex2str(alldata[alldata[laddr.con.value]]); 1149 | tinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 1150 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1151 | takeaction = True; 1152 | elif laddr.tag == "Iex_Const" and laddr.con.value in alldata and not isinstance(alldata[laddr.con.value],int): 1153 | fresult = hex2str(alldata[laddr.con.value]); 1154 | tinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 1155 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1156 | takeaction = True; 1157 | elif laddr.tag == "Iex_RdTmp" and tinfo.gettrace(sitem.tmp,ARGTYPE.Vtmp): 1158 | v = 0; 1159 | vtype = ARGTYPE.Vunkown; 1160 | if node.instack(laddr.tmp,ARGTYPE.Vtmp): 1161 | tmpvstackdata = node.getstackdata(laddr.tmp,ARGTYPE.Vtmp); 1162 | v = tmpvstackdata[0]; 1163 | vtype = tmpvstackdata[1]; 1164 | if vtype == ARGTYPE.Voffset: 1165 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 1166 | elif vtype == ARGTYPE.Vtmp: 1167 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 1168 | elif vtype == ARGTYPE.Vconst: 1169 | if v in alldata and isinstance(alldata[v],int)and alldata[v] in alldata: 1170 | fresult = hex2str(alldata[alldata[v]]); 1171 | tinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 1172 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1173 | takeaction = True; 1174 | elif v in alldata and not isinstance(alldata[v],int): 1175 | fresult = hex2str(alldata[laddr.con.value]); 1176 | tinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,fresult); 1177 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1178 | takeaction = True; 1179 | elif vtype == ARGTYPE.Vunkown: 1180 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,laddr.tmp,ARGTYPE.Vtmp); 1181 | actionv.append(laddr.tmp); 1182 | actiont.append(ARGTYPE.Vtmp); 1183 | elif tinfo.getargtype(sitem.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vint: 1184 | if laddr.tag == "Iex_Const": 1185 | tinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,laddr.con.value); 1186 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1187 | elif laddr.tag == "Iex_RdTmp" and node.instack(laddr.tmp,ARGTYPE.Vtmp): 1188 | takeaction = True; 1189 | stacklocatinfo = node.getstackdata(laddr.tmp ,ARGTYPE.Vtmp); 1190 | v = stacklocatinfo[0]; 1191 | vtype = stacklocatinfo[1]; 1192 | #print(vtype); 1193 | if vtype == ARGTYPE.Voffset: 1194 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Voffset); 1195 | elif vtype == ARGTYPE.Vtmp: 1196 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Vtmp); 1197 | elif vtype == ARGTYPE.Vconst: 1198 | tinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,v); 1199 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1200 | elif vtype == ARGTYPE.Vunkown: 1201 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,laddr.tmp,ARGTYPE.Vtmp); 1202 | actionv.append(laddr.tmp); 1203 | actiont.append(ARGTYPE.Vtmp); 1204 | elif laddr.tag == "Iex_RdTmp": 1205 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,laddr.tmp,ARGTYPE.Vtmp); 1206 | 1207 | elif eitem.tag == "Iex_Const": 1208 | if tinfo.getargtype(sitem.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vint: 1209 | takeaction = True; 1210 | tinfo.setfresult(sitem.tmp,ARGTYPE.Vtmp,eitem.con.value); 1211 | tinfo.setntrace(sitem.tmp,ARGTYPE.Vtmp); 1212 | actionv.append(sitem.tmp); 1213 | actiont.append(ARGTYPE.Vtmp); 1214 | elif eitem.tag == "Iex_Binop": 1215 | takeaction = True; 1216 | actionv.append(sitem.tmp); 1217 | actiont.append(ARGTYPE.Vtmp); 1218 | elif eitem.tag == "Iex_Get": 1219 | takeaction = True; 1220 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,eitem.offset,ARGTYPE.Voffset); 1221 | actionv.append(eitem.offset); 1222 | actiont.append(ARGTYPE.Voffset); 1223 | elif sitem.tag == "Ist_Store": 1224 | if sitem.addr.tag == "Iex_Const": 1225 | if tinfo.keyin(sitem.addr.constants[0].value,ARGTYPE.Vconst) and tinfo.gettrace(sitem.addr.constants[0].value,ARGTYPE.Vconst): 1226 | eitem = sitem.data; 1227 | if eitem.tag == "Iex_Const": 1228 | if tinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vint: 1229 | tinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,eitem.con.value); 1230 | tinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 1231 | takeaction = True; 1232 | elif tinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vstring: 1233 | if eitem.con.value in alldata and isinstance(alldata[eitem.con.value],int)and alldata[eitem.con.value] in alldata: 1234 | fresult = hex2str(alldata[alldata[eitem.con.value]]); 1235 | tinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 1236 | tinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 1237 | takeaction = True; 1238 | elif eitem.con.value in alldata and not isinstance(alldata[eitem.con.value],int): 1239 | fresult = hex2str(alldata[eitem.con.value]); 1240 | tinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 1241 | tinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 1242 | takeaction = True; 1243 | else: 1244 | tinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,eitem.con.value,ARGTYPE.Vconst); 1245 | actionv.append(eitem.con.value); 1246 | actiont.append(ARGTYPE.Vconst); 1247 | takeaction = True; 1248 | elif eitem.tag == "Iex_RdTmp": 1249 | if tinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vint: 1250 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 1251 | takeaction = True; 1252 | stacklocatinfo = node.getstackdata(eitem.tmp ,ARGTYPE.Vtmp); 1253 | v = stacklocatinfo[0]; 1254 | vtype = stacklocatinfo[1]; 1255 | if vtype == ARGTYPE.Voffset: 1256 | tinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,ARGTYPE.Voffset); 1257 | elif vtype == ARGTYPE.Vtmp: 1258 | tinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,ARGTYPE.Vtmp); 1259 | elif vtype == ARGTYPE.Vconst: 1260 | tinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,v); 1261 | tinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 1262 | elif tinfo.getargtype(sitem.addr.constants[0].value,ARGTYPE.Vconst) == FARGTYPE.Vstring: 1263 | v = 0; 1264 | vtype = ARGTYPE.Vunkown; 1265 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 1266 | tmpvstackdata = node.getstackdata(eitem.tmp,ARGTYPE.Vtmp); 1267 | v = tmpvstackdata[0]; 1268 | vtype = tmpvstackdata[1]; 1269 | if vtype == ARGTYPE.Voffset: 1270 | tinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,vtype); 1271 | elif vtype == ARGTYPE.Vtmp: 1272 | tinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,v,vtype); 1273 | elif vtype == ARGTYPE.Vconst: 1274 | if v in alldata and isinstance(alldata[v],int)and alldata[v] in alldata: 1275 | fresult = hex2str(alldata[alldata[v]]); 1276 | tinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 1277 | tinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 1278 | takeaction = True; 1279 | elif v in alldata and not isinstance(alldata[v],int): 1280 | fresult = hex2str(alldata[laddr.con.value]); 1281 | tinfo.setfresult(sitem.addr.constants[0].value,ARGTYPE.Vconst,fresult); 1282 | tinfo.setntrace(sitem.addr.constants[0].value,ARGTYPE.Vconst); 1283 | takeaction = True; 1284 | elif vtype == ARGTYPE.Vunkown: 1285 | tinfo.keyupdate(sitem.addr.constants[0].value,ARGTYPE.Vconst,eitem.tmp,ARGTYPE.Vtmp); 1286 | actionv.append(eitem.tmp); 1287 | actiont.append(ARGTYPE.Vtmp); 1288 | takeaction = True; 1289 | elif sitem.addr.tag == "Iex_RdTmp": 1290 | if tinfo.keyin(sitem.addr.tmp,ARGTYPE.Vtmp) and tinfo.gettrace(sitem.addr.tmp,ARGTYPE.Vtmp): 1291 | eitem = sitem.data; 1292 | if eitem.tag == "Iex_Const": 1293 | if tinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vint: 1294 | tinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.con.value); 1295 | tinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1296 | takeaction = True; 1297 | elif tinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vstring: 1298 | if eitem.con.value in alldata and isinstance(alldata[eitem.con.value],int)and alldata[eitem.con.value] in alldata: 1299 | fresult = hex2str(alldata[alldata[eitem.con.value]]); 1300 | tinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 1301 | tinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp,ARGTYPE.Vconst); 1302 | takeaction = True; 1303 | elif eitem.con.value in alldata and not isinstance(alldata[eitem.con.value],int): 1304 | fresult = hex2str(alldata[eitem.con.value]); 1305 | tinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 1306 | tinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1307 | takeaction = True; 1308 | else: 1309 | tinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.con.value,ARGTYPE.Vconst); 1310 | actionv.append(eitem.con.value); 1311 | actiont.append(ARGTYPE.Vconst); 1312 | takeaction = True; 1313 | elif eitem.tag == "Iex_RdTmp": 1314 | if tinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vint: 1315 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 1316 | takeaction = True; 1317 | stacklocatinfo = node.getstackdata(eitem.tmp ,ARGTYPE.Vtmp); 1318 | v = stacklocatinfo[0]; 1319 | vtype = stacklocatinfo[1]; 1320 | if vtype == ARGTYPE.Voffset: 1321 | tinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Voffset); 1322 | elif vtype == ARGTYPE.Vtmp: 1323 | tinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,v,ARGTYPE.Vtmp); 1324 | elif vtype == ARGTYPE.Vconst: 1325 | tinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,v); 1326 | tinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1327 | elif tinfo.getargtype(sitem.addr.tmp,ARGTYPE.Vtmp) == FARGTYPE.Vstring: 1328 | v = 0; 1329 | vtype = ARGTYPE.Vunkown; 1330 | if node.instack(eitem.tmp,ARGTYPE.Vtmp): 1331 | tmpvstackdata = node.getstackdata(eitem.tmp,ARGTYPE.Vtmp); 1332 | v = tmpvstackdata[0]; 1333 | vtype = tmpvstackdata[1]; 1334 | if vtype == ARGTYPE.Voffset: 1335 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 1336 | elif vtype == ARGTYPE.Vtmp: 1337 | tinfo.keyupdate(sitem.tmp,ARGTYPE.Vtmp,v,vtype); 1338 | elif vtype == ARGTYPE.Vconst: 1339 | if v in alldata and isinstance(alldata[v],int)and alldata[v] in alldata: 1340 | fresult = hex2str(alldata[alldata[v]]); 1341 | tinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 1342 | tinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1343 | takeaction = True; 1344 | elif v in alldata and not isinstance(alldata[v],int): 1345 | fresult = hex2str(alldata[laddr.con.value]); 1346 | tinfo.setfresult(sitem.addr.tmp,ARGTYPE.Vtmp,fresult); 1347 | tinfo.setntrace(sitem.addr.tmp,ARGTYPE.Vtmp); 1348 | takeaction = True; 1349 | elif vtype == ARGTYPE.Vunkown: 1350 | tinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.tmp,ARGTYPE.Vtmp); 1351 | actionv.append(eitem.tmp); 1352 | actiont.append(ARGTYPE.Vtmp); 1353 | tinfo.keyupdate(sitem.addr.tmp,ARGTYPE.Vtmp,eitem.tmp,ARGTYPE.Vtmp); 1354 | actionv.append(eitem.tmp); 1355 | actiont.append(ARGTYPE.Vtmp); 1356 | takeaction = True; 1357 | #if node.beginaddr == 0x402dd8 or node.beginaddr == 0x10550: 1358 | # print("middle0x%X"%node.beginaddr); 1359 | # tinfo.listdebugpp(); 1360 | # print(node.stack); 1361 | # print(node.sprelate); 1362 | for i in range(0,tinfo.alllen()): 1363 | vv = tinfo.getindexvl(i); 1364 | vtypev = tinfo.getindexvtypel(i); 1365 | if ntinfo.keyin(vv,vtypev) and not ntinfo.gettrace(vv,vtypev): 1366 | tinfo.setfresult(vv,vtypev,ntinfo.getfresult(vv,vtypev)); 1367 | tinfo.setfaddr(vv,vtypev,ntinfo.getfaddr(vv,vtypev)); 1368 | tinfo.setntrace(vv,vtypev); 1369 | for i in range(0,len(tinfo.vtypel)): 1370 | if tinfo.vtypel[i] == ARGTYPE.Vconst: 1371 | v = tinfo.vl[i]; 1372 | if v in alldata: 1373 | tinfo.setfresult(v,tinfo.vtypel[i],alldata[v]); 1374 | tinfo.setntrace(v,tinfo.vtypel[i]); 1375 | for indexvt in range(0,len(tinfo.vtypel)): 1376 | if not tinfo.vtypel[indexvt] == ARGTYPE.Vtmp: 1377 | continue; 1378 | elif not (tinfo.keyin(tinfo.vl[indexvt],tinfo.vtypel[indexvt]) and tinfo.gettrace(tinfo.vl[indexvt],tinfo.vtypel[indexvt])): 1379 | continue; 1380 | elif not str(tinfo.vl[indexvt]) + " " + str(tinfo.vtypel[indexvt]) in node.sprelate: 1381 | continue; 1382 | else: 1383 | tinfo.keyupdate(tinfo.vl[indexvt],tinfo.vtypel[indexvt],node.sprelate[str(tinfo.vl[indexvt]) + " " + str(tinfo.vtypel[indexvt])]/node.getwordlen() + node.stackfixnum,ARGTYPE.Vstackv); 1384 | #if node.beginaddr == 0x402dd8 or node.beginaddr == 0x10550: 1385 | # print("end0x%X"%node.beginaddr); 1386 | # tinfo.listdebugpp(); 1387 | # print(node.stack); 1388 | # print(node.sprelate); 1389 | tinfo.listallpp(detailreport); 1390 | tinfo.settntrace(); 1391 | if node.beginaddr in allfn: 1392 | dfun = traceinfo2func(tinfo,node,allfn[node.beginaddr]); 1393 | if dfun.getfunctionname() in ef: 1394 | middlefunc[dfun.getfunctionname()] = dfun; 1395 | if tinfo.ntlen() == 0: 1396 | return; 1397 | for pitem in node.getparents(): 1398 | reversetracedfs(pitem,traceinfocopy(tinfo),offset,alldata,node.stackoffset,depth+1,execfuncdetail,allfn,middlefunc,ef,detailreport,wfuncsetreturn,copy.copy(pathroad)); 1399 | 1400 | def reversetrans(nodeset,function,offset,alldata,execfuncdetail,allfuncn,ef,detailreport,wfuncsetreturn): 1401 | node = nodeset[0]; 1402 | ti = func2traceinfo(function,node.beginaddr); 1403 | middlefunc = dict(); 1404 | reversetracedfs(nodeset,ti,offset,alldata,0,1,execfuncdetail,allfuncn,middlefunc,ef,detailreport,wfuncsetreturn,set()); 1405 | return middlefunc; 1406 | 1407 | def writetime(filename,promt,time): 1408 | f = open(filename,"a"); 1409 | f.write(promt + "\n"); 1410 | f.write(str(time)); 1411 | f.write("\n"); 1412 | f.close(); 1413 | 1414 | def transbin2IR(filename,outputname,importfc = dict()): 1415 | result = dict(); 1416 | global nextblocktime; 1417 | nextblocktime = 0; 1418 | detailreport = dict(); 1419 | funcnameset,funcdetail,ruledesdic,wfuncsetreturn,wfuncdetail = rulematch(); 1420 | outputtime = outputname + "time"; 1421 | print("time:%s"%outputtime); 1422 | funcnameset = funcnameset.union(importfc.keys()) 1423 | funcdetail.update(importfc); 1424 | print("beginlift"); 1425 | testbegintime = time.time(); 1426 | binfile,allfunc,allfuncname,lcom,pltstype,rodatatype,datatype,functiondata,functionsp,innerfunctions,externfunctions,functionmap,alldata,externfuncset = binlcominfo(filename); 1427 | if os.path.getsize(binfile) / float(1024*1024) > 10: 1428 | return result,detailreport; 1429 | print("size:%d"%os.path.getsize(binfile)); 1430 | #if len(externfuncset&funcnameset) == 0: 1431 | # return result,detailreport; 1432 | exportedfunc = nmfile(binfile); 1433 | print(binfile); 1434 | proj = angr.Project(binfile,load_options={'auto_load_libs': False}); 1435 | resulttype,offset = execorlib(binfile); 1436 | cfg = None; 1437 | try: 1438 | if resulttype == FILETYPE.Vxexec: 1439 | cfg = proj.analyses.CFG(); 1440 | else: 1441 | cfg = proj.analyses.CFG(); 1442 | except BaseException: 1443 | print("BaseException"); 1444 | testendtime = time.time(); 1445 | wtime = testendtime-testbegintime; 1446 | writetime(outputtime,"lift to IR",wtime); 1447 | print("lift to IR %f"%wtime); 1448 | return result,detailreport; 1449 | except Exception: 1450 | testendtime = time.time(); 1451 | wtime = testendtime-testbegintime; 1452 | writetime(outputtime,"lift to IR",wtime); 1453 | print("lift to IR %f"%wtime); 1454 | print("Exception"); 1455 | return result,detailreport; 1456 | funcdic = dict(proj.kb.functions); 1457 | msg = ""; 1458 | alladdrset = set(); 1459 | #wfd = open("/home/zhangli/zhangli/1.txt","w"); 1460 | for item in funcdic: 1461 | d = funcdic[item]; 1462 | #print(dir(d)); 1463 | blockset = d.block_addrs_set; 1464 | bl = list(blockset); 1465 | for b in bl: 1466 | block = proj.factory.block(b); 1467 | irsb = block.vex; 1468 | functionnode = problock(irsb,lcom); 1469 | msg = functionnode.getstr(); 1470 | #wfd.write(msg); 1471 | #wfd.close(); 1472 | testendtime = time.time(); 1473 | print("endlift"); 1474 | wtime = testendtime-testbegintime; 1475 | writetime(outputtime,"lift to IR",wtime); 1476 | print("lift to IR %f"%wtime); 1477 | externfunctiondic.clear(); 1478 | for item in funcdic: 1479 | alladdrset = alladdrset.union(funcdic[item].block_addrs_set); 1480 | mycfg = dict(); 1481 | testbegintime = time.time(); 1482 | global starttime; 1483 | for item in funcdic: 1484 | if len(funcdic[item].block_addrs_set) == 0: 1485 | continue; 1486 | b = funcdic[item].addr; 1487 | if b in mycfg: 1488 | continue; 1489 | block=proj.factory.block(b); 1490 | irsb = block.vex; 1491 | node=problock(irsb,lcom); 1492 | starttime = time.time(); 1493 | node,leafset = constructmycfg(node,proj,functionmap,lcom,mycfg,alladdrset,copy.copy(set()),0,None); 1494 | mycfg[b] = [node,leafset]; 1495 | testendtime = time.time(); 1496 | wtime = testendtime-testbegintime; 1497 | writetime(outputtime,"construct cfg",wtime); 1498 | print("construct cfg %f"%wtime); 1499 | print(nextblocktime); 1500 | execfuncset,execfuncdetail = execfunction(); 1501 | for key in lcom: 1502 | if not len(lcom[key]) == 0: 1503 | lcom[key] = lcom[key][1:]; 1504 | testbegintime = time.time(); 1505 | for item in externfunctiondic: 1506 | for elitem in externfunctiondic[item]: 1507 | if not elitem.getexternfun() in funcnameset: 1508 | continue; 1509 | function = funcdetail[elitem.getexternfun()]; 1510 | print(elitem.getexternfun()); 1511 | for pitem in elitem.getparents(): 1512 | finishfuncdetail(function,pitem[0]); 1513 | #global starttime; 1514 | starttime = time.time(); 1515 | tmpresult = reversetrans(pitem,function,offset,alldata,execfuncdetail,allfuncname,exportedfunc,detailreport,wfuncsetreturn); 1516 | result.update(tmpresult); 1517 | testendtime = time.time(); 1518 | wtime = testendtime-testbegintime; 1519 | writetime(outputtime,"tain",wtime); 1520 | print("tain %f"%wtime); 1521 | return result,detailreport; 1522 | --------------------------------------------------------------------------------