-
-
[原创] KCTF 2019 Q1 第七题 混淆模式清除 与 随机位权大数规整
-
发表于: 2019-3-24 01:08 5765
-
太绕,精力有限,这里只做部分分析
0x00 混淆清除
0x01 随机位权大数归整
0x00 混淆清除
用法,针对其八种混淆模型进行nop清除,以还原构建函数控制流
(1)IDAPython里复制粘贴下述所有代码
(2)然后鼠标定位再需要清除混淆的地方,IDAPython运行 cnop(0,1) (注意cnop(0,0)只列出混淆片段,不nop)
(3)cnop 参数1可以直接提供地址,地址最好选在模式之前,(否则会寻的不到)
(4)默认搜索长度是当前位置(若参数1为0)或参数1所提供地址开始的0x100长度代码区间,设计采用Original字节信息(GetOriginalByte函数,所以可以反复多次执行
(5)执行后,需要手动快捷键“u”( 打回未定义原形
)与‘c’(启动片区代码分析)
def check_nop_call_add_esp_4(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" call_add_esp_list = [] for ea in e8_call_list: if Dword(ea+1) < 0x100: tea = ea+5+Dword(ea+1) if Dword(tea)&0xFFFFFF == 0x04C483: call_add_esp_list.append([ea,tea+3]) for s,e in call_add_esp_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M1: {:X} to {:X}".format(s,e) def check_nop_dualjmp(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 dualjmp = [[0x70,0x71],[0x72,0x73],[0x74,0x75],[0x76,0x77],[0x78,0x79],[0x7a,0x7b],[0x7C,0x7D], [0x7e,0x7f]] #jo,jno;jb,jnb;jz,jnz;jbe,ja;js,jns;jp,jnp;jl,jge; #jle,jg; while i < zonelen: for dj in dualjmp: if (Byte(ea+i) in dj) and (Byte(ea+i+2) in dj) and (Byte(ea+i+1)==(Byte(ea+i+3)+2)): mea_list.append(ea+i) i+=4 break else: i+=1 #check nop se_list = [] for ea in mea_list: se_list.append([ea,ea+2+Byte(ea+1)]) for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M2: {:X} to {:X}".format(s,e) def check_nop_push_call_pop_pop(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" push_call_pop_pop_list = [] for ea in e8_call_list: if (Byte(ea-1)==0x50) and (Dword(ea+1) < 0x100): tea = ea+5+Dword(ea+1) if Dword(tea)&0xFFFF == 0x5858: push_call_pop_pop_list.append([ea-1,tea+2]) for s,e in push_call_pop_pop_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M3: {:X} to {:X}".format(s,e) def check_nop_call_add_6(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" call_add_6_list = [] for ea in e8_call_list: if (Dword(ea+1) < 0x100): tea = ea+5+Dword(ea+1) if Qword(tea)&0xFFFFFFFFFF == 0xC306240483: call_add_6_list.append([ea,tea+5]) for s,e in call_add_6_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M4: {:X} to {:X}".format(s,e) def check_nop_flagjmp(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 flagjmp = [0x73F8,0x72F9] #clc,jnb;stc,jb while i < zonelen: if (Word(ea+i) in flagjmp) and (Byte(ea+i+2)<0x40): mea_list.append(ea+i) i+=3 else: i+=1 #check nop se_list = [] for ea in mea_list: se_list.append([ea,ea+3+Byte(ea+2)]) for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M5: {:X} to {:X}".format(s,e) def check_nop_jljmpjz(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 flagjmp = [0x73F8,0x72F9] #clc,jnb;stc,jb while i < zonelen: if Qword(ea+i)&0x00FFFF00FFFFFFFF == 0xFB740003EB037C: mea_list.append(ea+i) i+=7 else: i+=1 #check nop se_list = [] for ea in mea_list: se_list.append([ea,ea+7]) for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M6: {:X} to {:X}".format(s,e) def check_nop_4jmp(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 se_list = [] while i < zonelen: j1,o1,x1,j2,o2,x2,j3,o3,x3,j4,o4,x4 = struct.unpack("BbBBbBBbBBbB",get_bytes(ea+i,12)) if [j1,j2,j3,j4].count(0xEB) == 4: oo = [o1,o2,o3,o4] t1 = 2+oo[0] t2 = t1+2+oo[t1/3] t3 = t2+2+oo[t2/3] t4 = t3+2+oo[t3/3] t = ea+i+t4 se_list.append([ea+i,t]) i+=12 else: i+=1 #check nop for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M7: {:X} to {:X}".format(s,e) def check_nop_call_pop_inc_jjmpreg(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" mea_list = [] poplist = [0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F]#eax,ecx,edx,ebx,esp,ebp,esi,edi inclist = [0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47] jreglist = [0xE0FF,0xE1FF,0xE2FF,0xE3FF,0xE4FF,0xE5FF,0xE6FF,0xE7FF] for ea in e8_call_list: if(Dword(ea+1) < 0x100):#check call offset tea = ea+5+Dword(ea+1) #pop reg if Byte(tea) in poplist and Byte(tea+1) == 0xEB: pidx = poplist.index(Byte(tea)) pjmp_ea = tea+3+c_byte(Byte(tea+2)).value #inc reg if (Byte(pjmp_ea) in inclist) and (Byte(pjmp_ea+1) == 0xEB) and (inclist.index(Byte(pjmp_ea)) ==pidx): iidx = inclist.index(Byte(pjmp_ea)) ijmp_ea = pjmp_ea+3+c_byte(Byte(pjmp_ea+2)).value if (Word(ijmp_ea) in jreglist) and (jreglist.index(Word(ijmp_ea)) == pidx): cjea = ea+5+1 rea = cjea + 2 + c_byte(Byte(cjea+1)).value mea_list.append([ea,rea]) for s,e in mea_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M8: {:X} to {:X}".format(s,e) def cnop(ea=0,b=False,zonelen = 0x100): check_nop_4jmp(ea,b,zonelen) check_nop_jljmpjz(ea,b,zonelen) check_nop_flagjmp(ea,b,zonelen) check_nop_call_add_6(ea,b,zonelen) check_nop_call_add_esp_4(ea,b,zonelen) check_nop_dualjmp(ea,b,zonelen) check_nop_push_call_pop_pop(ea,b,zonelen) check_nop_call_pop_inc_jjmpreg(ea,b,zonelen)
def check_nop_call_add_esp_4(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" call_add_esp_list = [] for ea in e8_call_list: if Dword(ea+1) < 0x100: tea = ea+5+Dword(ea+1) if Dword(tea)&0xFFFFFF == 0x04C483: call_add_esp_list.append([ea,tea+3]) for s,e in call_add_esp_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M1: {:X} to {:X}".format(s,e) def check_nop_dualjmp(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 dualjmp = [[0x70,0x71],[0x72,0x73],[0x74,0x75],[0x76,0x77],[0x78,0x79],[0x7a,0x7b],[0x7C,0x7D], [0x7e,0x7f]] #jo,jno;jb,jnb;jz,jnz;jbe,ja;js,jns;jp,jnp;jl,jge; #jle,jg; while i < zonelen: for dj in dualjmp: if (Byte(ea+i) in dj) and (Byte(ea+i+2) in dj) and (Byte(ea+i+1)==(Byte(ea+i+3)+2)): mea_list.append(ea+i) i+=4 break else: i+=1 #check nop se_list = [] for ea in mea_list: se_list.append([ea,ea+2+Byte(ea+1)]) for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M2: {:X} to {:X}".format(s,e) def check_nop_push_call_pop_pop(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" push_call_pop_pop_list = [] for ea in e8_call_list: if (Byte(ea-1)==0x50) and (Dword(ea+1) < 0x100): tea = ea+5+Dword(ea+1) if Dword(tea)&0xFFFF == 0x5858: push_call_pop_pop_list.append([ea-1,tea+2]) for s,e in push_call_pop_pop_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M3: {:X} to {:X}".format(s,e) def check_nop_call_add_6(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" call_add_6_list = [] for ea in e8_call_list: if (Dword(ea+1) < 0x100): tea = ea+5+Dword(ea+1) if Qword(tea)&0xFFFFFFFFFF == 0xC306240483: call_add_6_list.append([ea,tea+5]) for s,e in call_add_6_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M4: {:X} to {:X}".format(s,e) def check_nop_flagjmp(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 flagjmp = [0x73F8,0x72F9] #clc,jnb;stc,jb while i < zonelen: if (Word(ea+i) in flagjmp) and (Byte(ea+i+2)<0x40): mea_list.append(ea+i) i+=3 else: i+=1 #check nop se_list = [] for ea in mea_list: se_list.append([ea,ea+3+Byte(ea+2)]) for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M5: {:X} to {:X}".format(s,e) def check_nop_jljmpjz(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 flagjmp = [0x73F8,0x72F9] #clc,jnb;stc,jb while i < zonelen: if Qword(ea+i)&0x00FFFF00FFFFFFFF == 0xFB740003EB037C: mea_list.append(ea+i) i+=7 else: i+=1 #check nop se_list = [] for ea in mea_list: se_list.append([ea,ea+7]) for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M6: {:X} to {:X}".format(s,e) def check_nop_4jmp(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() mea_list = [] i = 0 se_list = [] while i < zonelen: j1,o1,x1,j2,o2,x2,j3,o3,x3,j4,o4,x4 = struct.unpack("BbBBbBBbBBbB",get_bytes(ea+i,12)) if [j1,j2,j3,j4].count(0xEB) == 4: oo = [o1,o2,o3,o4] t1 = 2+oo[0] t2 = t1+2+oo[t1/3] t3 = t2+2+oo[t2/3] t4 = t3+2+oo[t3/3] t = ea+i+t4 se_list.append([ea+i,t]) i+=12 else: i+=1 #check nop for s,e in se_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M7: {:X} to {:X}".format(s,e) def check_nop_call_pop_inc_jjmpreg(ea = 0,bnop = False,zonelen = 0x100): if ea == 0: ea = ScreenEA() e8_call_list = [] i = 0 while i < zonelen: if Byte(ea+i)==0xE8: e8_call_list.append(ea+i) i+=5 else: i+=1 #check if is "call to add esp,4" mea_list = [] poplist = [0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F]#eax,ecx,edx,ebx,esp,ebp,esi,edi inclist = [0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47] jreglist = [0xE0FF,0xE1FF,0xE2FF,0xE3FF,0xE4FF,0xE5FF,0xE6FF,0xE7FF] for ea in e8_call_list: if(Dword(ea+1) < 0x100):#check call offset tea = ea+5+Dword(ea+1) #pop reg if Byte(tea) in poplist and Byte(tea+1) == 0xEB: pidx = poplist.index(Byte(tea)) pjmp_ea = tea+3+c_byte(Byte(tea+2)).value #inc reg if (Byte(pjmp_ea) in inclist) and (Byte(pjmp_ea+1) == 0xEB) and (inclist.index(Byte(pjmp_ea)) ==pidx): iidx = inclist.index(Byte(pjmp_ea)) ijmp_ea = pjmp_ea+3+c_byte(Byte(pjmp_ea+2)).value if (Word(ijmp_ea) in jreglist) and (jreglist.index(Word(ijmp_ea)) == pidx): cjea = ea+5+1 rea = cjea + 2 + c_byte(Byte(cjea+1)).value mea_list.append([ea,rea]) for s,e in mea_list: if bnop: for ea in range(s,e): PatchByte(ea,0x90) print "M8: {:X} to {:X}".format(s,e) def cnop(ea=0,b=False,zonelen = 0x100): check_nop_4jmp(ea,b,zonelen) check_nop_jljmpjz(ea,b,zonelen) check_nop_flagjmp(ea,b,zonelen) check_nop_call_add_6(ea,b,zonelen) check_nop_call_add_esp_4(ea,b,zonelen) check_nop_dualjmp(ea,b,zonelen) check_nop_push_call_pop_pop(ea,b,zonelen) check_nop_call_pop_inc_jjmpreg(ea,b,zonelen)
如,以下是清除混淆后,主函数main的F5伪码
int __cdecl main(int argc,const char**argv,const char**envp) { myvect*v3;// ebx myvect*v4;// edi int v5;// esi void*v6;// esp myvect*v7;// ecx int v8;// eax int v9;// edx int v10;// eax char*v11;// ebx myvect*v12;// esi char*v13;// edx char v14;// ah char v15;// dl int v16;// eax DWORD v17;// eax myvect*v18;// edx DWORD v19;// ebx int v20;// eax int v21;// ebx DWORD v22;// eax int v23;// edx int v24;// edx int v25;// ecx signed int v26;// eax int(*v27)();// eax DWORD v28;// ebx __int64 v29;// rax __int64 v30;// rax char v31;// al myvect*v32;// edx int v33;// eax int v34;// ST20_4 unsigned __int8*v35;// ST1C_4 int v36;// eax _BYTE*v37;// ecx int v38;// eax int v39;// ebx int v40;// edx int v41;// eax int v42;// edx int v44;// [esp+4h] [ebp-2BDCh] int v45;// [esp+8h] [ebp-2BD8h] int loc_off1;// [esp+Ch] [ebp-2BD4h] int loc_keydidx;// [esp+10h] [ebp-2BD0h] int loc_srcBigNum_idx;// [esp+14h] [ebp-2BCCh] int loc_tmp;// [esp+18h] [ebp-2BC8h] int v50;// [esp+18h] [ebp-2BC8h] int loc_gbnidx;// [esp+1Ch] [ebp-2BC4h] signed int loc_ii_0_to_ValSub9;// [esp+20h] [ebp-2BC0h] signed int loc_BitWeightVal;// [esp+24h] [ebp-2BBCh] int loc_BitWeightVal_var_2BBCa;// [esp+24h] [ebp-2BBCh] myvect*loc_BitWeightVal_var_2BBCb;// [esp+24h] [ebp-2BBCh] int loc_vocidx_0x4F;// [esp+28h] [ebp-2BB8h] myvect*v57;// [esp+28h] [ebp-2BB8h] int v58;// [esp+28h] [ebp-2BB8h] int loc_watch1;// [esp+2Ch] [ebp-2BB4h] int loc_watch1a;// [esp+2Ch] [ebp-2BB4h] signed int loc_watch1b;// [esp+2Ch] [ebp-2BB4h] int loc_watch1c;// [esp+2Ch] [ebp-2BB4h] int loc_keylen;// [esp+30h] [ebp-2BB0h] char v64;// [esp+34h] [ebp-2BACh] int loc_tryl;// [esp+38h] [ebp-2BA8h] int(__cdecl*v66)(int,int,int,int,int,int);// [esp+4Ch] [ebp-2B94h] int*v67;// [esp+50h] [ebp-2B90h] myvect**v68;// [esp+54h] [ebp-2B8Ch] void*v69;// [esp+58h] [ebp-2B88h] myvect**v70;// [esp+5Ch] [ebp-2B84h] myvect loc_vect_V0C;// [esp+68h] [ebp-2B78h] int v72;// [esp+74h] [ebp-2B6Ch] myvect loc_vect_buf510;// [esp+80h] [ebp-2B60h] myvect nlw;// [esp+8Ch] [ebp-2B54h] char loc_keystr[256];// [esp+A8h] [ebp-2B38h] char loc_keyh[256];// [esp+1A8h] [ebp-2A38h] char loc_keyd[256];// [esp+2A8h] [ebp-2938h] char loc_BitNum1[5136];// [esp+3A8h] [ebp-2838h] char loc_BitNum2[5136];// [esp+17B8h] [ebp-1428h] myvect*var_18;// [esp+2BC8h] [ebp-18h] myvect*v81;// [esp+2BCCh] [ebp-14h] int v82;// [esp+2BD0h] [ebp-10h] myvect*v83;// [esp+2BD4h] [ebp-Ch] int*v84;// [esp+2BD8h] [ebp-8h] int v85;// [esp+2BDCh] [ebp-4h] int retaddr;// [esp+2BE0h] [ebp+0h] v85=retaddr; v84=&retaddr; v83=v4; v82=v5; v81=v3; v6=alloca(Hi_stack_alloc((unsigned int)&argc)); v66=sub_4B85B0; v67=dword_4B9D1C; v69=&unk_4B9827; v68=&var_18; v70=&var_18; Hi_esp_check_in(&v64); sub_40C510(); Hi_set_debuginfo_sub_40299C(4096); Hi_ecx_BitNum_ClockRandBitWeight(loc_BitNum1); Hi_ecx_BitNum_ClockRandBitWeight(loc_BitNum2); loc_tryl=2; Hi_like_scanf_key(&Hi_input_io,loc_keystr); for(loc_keylen=0;;++loc_keylen) { v8=loc_keylen; if(!loc_keystr[loc_keylen]) break; } v9=0; LOBYTE(v3)=55; while(v9!=loc_keylen) { LOBYTE(v8)=loc_keystr[v9]; LOBYTE(v7)=48; if((char)v8>57) { LOBYTE(v7)=61; if((char)v8<'a' ) v7=v3; } v10=v8-(_DWORD)v7; loc_keyh[v9]=v10; v8=v10-1; if((unsigned __int8)v8>0xEu) goto LABEL_61; ++v9; } v11=loc_keyd; v12=(myvect*)loc_keyh; loc_keyh[loc_keylen]=0; while(loc_keylen) { v13=&loc_keyh[loc_keylen]; do { v14=(unsigned __int8)*v13%0xAu; *v13=(unsigned __int8)*v13/0xAu; *(v13---1)+=16*v14; } while(loc_keyh!=v13); v15=loc_keyh[0]%0xAu; loc_keyh[0]/=0xAu; *v11=v15; do { v4=(myvect*)loc_keylen; v16=loc_keylen-1; if(loc_keyh[loc_keylen-1]) break; --loc_keylen; } while(v16); ++v11; } loc_tryl=2; Hi_BitNum_ctor_P1bytes_P2Radix(&Hi_BigNum1_hbytes,16); v81=(myvect*)Hi_BitNum_ctor_P1bytes_P2Radix(&Hi_BigNum2_hbytes,16); Hi_ecx_BitNum_eq_ECX_mul_P1(loc_BitNum2); Hi_ecx_BitNum_radix_0Ah_to_10h(loc_BitNum1,v4); loc_vect_V0C.first=0; loc_vect_V0C.last=0; loc_vect_V0C.tail=0; loc_keydidx=0; loc_gbnidx=0; loc_srcBigNum_idx=0; loc_vocidx_0x4F=0; while(1) { loc_tryl=3; if(loc_srcBigNum_idx>=Hi_ecx_BitNum_get_BitCnt(loc_BitNum1)) break; loc_BitWeightVal=Hi_ecx_BitNum_get_BitWeightVal(loc_srcBigNum_idx); loc_vect_buf510.last=0; v17=Hi_malloc(0x510); v18=(myvect*)(v17+0x510); v19=v17; loc_vect_buf510.first=v17; v20=0; loc_vect_buf510.tail=(DWORD)v18; do { *(_DWORD*)(v19+v20)=0; v20+=4; } while(v20!=0x510); loc_vect_buf510.last=(DWORD)v18; if(loc_BitWeightVal) { if(loc_BitWeightVal<=9) { v30=loc_vocidx_0x4F; *(_DWORD*)(v19+4*v30)=1; *(_DWORD*)(v19+4*(loc_BitWeightVal+9*(unsigned __int64)(v30/9)+80))=1; v4=(myvect*)3; *(_DWORD*)(v19+4*(loc_BitWeightVal+9*(loc_vocidx_0x4F%9)+161))=1; v12=(myvect*)loc_BitWeightVal; *(_DWORD*)(v19+4*(loc_BitWeightVal+9*(3*(loc_vocidx_0x4F/27)+loc_vocidx_0x4F%9/3)+242))=1; loc_tryl=4; Hi_ecx_vect_0C_add_EleVect0Ch(&loc_vect_buf510); loc_tmp=loc_gbnidx+1; v81=(myvect*)Hi_ecx_BitNum_set_P1BitWeightIdx_P2value(loc_gbnidx,loc_BitWeightVal); var_18=v81; ++loc_vocidx_0x4F; } else { for(loc_ii_0_to_ValSub9=0;;++loc_ii_0_to_ValSub9) { loc_tmp=loc_ii_0_to_ValSub9+loc_gbnidx; loc_watch1=loc_ii_0_to_ValSub9+loc_vocidx_0x4F; if(loc_ii_0_to_ValSub9>=loc_BitWeightVal-9) break; v81=(myvect*)(unsigned __int8)loc_keyd[loc_keydidx+loc_ii_0_to_ValSub9]; loc_tryl=4; Hi_ecx_BitNum_set_P1BitWeightIdx_P2value(loc_tmp,v81); v81=(myvect*)loc_ii_0_to_ValSub9; var_18=(myvect*)loc_ii_0_to_ValSub9; loc_off1=4*loc_watch1; v21=9*(loc_watch1/9); v50=36*(loc_watch1/9)+0x144; v44=36*(loc_watch1/9)+0x168; v45=4*(9*(loc_watch1%9)-v21); loc_watch1a=4*(9*(loc_watch1%9/3+3*(loc_watch1/27))-v21); do { nlw.last=0; loc_tryl=4; v22=Hi_malloc(1296); nlw.first=v22; v23=0; nlw.tail=v22+1296; do { *(_DWORD*)(v22+v23)=0; v23+=4; } while(v23!=1296); v4=(myvect*)v50; nlw.last=v22+1296; *(_DWORD*)(v22+loc_off1)=1; *(_DWORD*)(v22+v50)=1; *(_DWORD*)(v50+v22+v45+324)=1; *(_DWORD*)(v50+loc_watch1a+v22+648)=1; loc_tryl=5; Hi_ecx_vect_0C_add_EleVect0Ch(&nlw); Hi_vect_release(&nlw,v24,v25); v50+=4; v12=(myvect*)v50; } while(v44!=v50); } loc_tryl=4; v26=Hi_ecx_BitNum_get_BitWeightVal(loc_srcBigNum_idx+1); var_18=v18; if(v26<=9) { loc_keydidx+=loc_ii_0_to_ValSub9; loc_vocidx_0x4F+=loc_ii_0_to_ValSub9; } else { v57=NULL; loc_BitWeightVal_var_2BBCa=0; do { v27=anti_debug_funcarray_off_4BC020[loc_BitWeightVal_var_2BBCa]; loc_tryl=4; v57=(myvect*)((char*)v57+((unsigned int)((int(__cdecl*)(myvect*))v27)(var_18)<1)); ++loc_BitWeightVal_var_2BBCa; } while(loc_BitWeightVal_var_2BBCa!=9); v28=loc_vect_buf510.first; v29=loc_watch1; *(_DWORD*)(loc_vect_buf510.first+4*v29)=1; *(_DWORD*)(v28+4*((_DWORD)v57+9*(unsigned __int64)(v29/9)+80))=1; v4=(myvect*)3; *(_DWORD*)(v28+4*((_DWORD)v57+9*(loc_watch1%9)+161))=1; v12=v57; *(_DWORD*)(v28+4*((_DWORD)v57+9*(3*(loc_watch1/27)+loc_watch1%9/3)+242))=1; loc_tryl=4; var_18=(myvect*)Hi_ecx_vect_0C_add_EleVect0Ch(&loc_vect_buf510); loc_vocidx_0x4F=loc_watch1+1; loc_keydidx+=loc_ii_0_to_ValSub9; } } } else { loc_tmp=loc_gbnidx; } Hi_vect_release(&loc_vect_buf510,v18,var_18); ++loc_srcBigNum_idx; loc_gbnidx=loc_tmp; } Hi_ecx_00h_vectV0C_eq_dowith_P1vectV0C_P2cnt_P3_0x144( &loc_vect_V0C, -1431655765*((signed int)(loc_vect_V0C.last-loc_vect_V0C.first)>>2), 324); loc_tryl=6; v31=sub_402DB6(0); var_18=v4; if(v31) { loc_tryl=6; Hi_myvect_ecx_ctor_P1((myvect*)((char*)&nlw+4)); var_18=v12; v58=0; loc_BitWeightVal_var_2BBCb=NULL; do { var_18=(myvect*)(loc_vect_V0C.first+12*(*(DWORD*)((char*)&loc_BitWeightVal_var_2BBCb->first+v72)-1)); loc_tryl=8; Hi_myvect_ecx_ctor_P1(var_18); var_18=loc_BitWeightVal_var_2BBCb; v32=(myvect*)loc_vect_buf510.first; loc_watch1b=0; do { if(*(_DWORD*)(loc_vect_buf510.first+4*loc_watch1b)==1) break; ++loc_watch1b; } while(loc_watch1b!=81); if(loc_watch1b==40) { --v58; } else { loc_watch1c=loc_watch1b-(loc_watch1b>=41); v33=0; do { if(*(_DWORD*)(loc_vect_buf510.first+4*v33+324)==1) break; ++v33; } while(v33!=81); v34=v33%9+1; loc_tryl=7; Hi_ecx_BitNum_get_BitWeightVal(loc_watch1c); v35=(unsigned __int8*)off_4BC060; v36=Hi_ecx_BitNum_get_BitWeightVal(loc_watch1c); var_18=v32; v58+=v34==v35[v36]; } Hi_vect_release(&loc_vect_buf510,v32,var_18); loc_BitWeightVal_var_2BBCb=(myvect*)((char*)loc_BitWeightVal_var_2BBCb+4); } while(loc_BitWeightVal_var_2BBCb!=(myvect*)324); v37=off_4BC05C; v38=0; do { v39=(unsigned __int8)v37[v38]; loc_keylen+=9*(v39^v58)^0x37; v40=v39^v58; v37[v38]=v39^v58; if(v58==v39) break; ++v38; } while(v38!=513); if(loc_keylen==7962) { loc_tryl=8; v41=sub_4B3F00(&dword_4BD9A0,(char*)off_4BC05C); sub_4B0DB0(v41); } Hi_vect_release(&v72,v40,var_18); } j_free(nlw.first); Hi_vect_release(&nlw.last,v42,var_18); sub_402966(&loc_vect_V0C); LABEL_61: sub_401570(loc_BitNum2); sub_401570(loc_BitNum1); Hi_esp_check_out(&v64); return 0; }
int __cdecl main(int argc,const char**argv,const char**envp) { myvect*v3;// ebx myvect*v4;// edi int v5;// esi void*v6;// esp myvect*v7;// ecx int v8;// eax int v9;// edx int v10;// eax char*v11;// ebx myvect*v12;// esi char*v13;// edx char v14;// ah char v15;// dl int v16;// eax DWORD v17;// eax myvect*v18;// edx DWORD v19;// ebx int v20;// eax int v21;// ebx DWORD v22;// eax int v23;// edx int v24;// edx int v25;// ecx signed int v26;// eax int(*v27)();// eax DWORD v28;// ebx __int64 v29;// rax __int64 v30;// rax char v31;// al myvect*v32;// edx int v33;// eax int v34;// ST20_4 unsigned __int8*v35;// ST1C_4 int v36;// eax _BYTE*v37;// ecx int v38;// eax int v39;// ebx int v40;// edx int v41;// eax int v42;// edx int v44;// [esp+4h] [ebp-2BDCh] int v45;// [esp+8h] [ebp-2BD8h] int loc_off1;// [esp+Ch] [ebp-2BD4h] int loc_keydidx;// [esp+10h] [ebp-2BD0h] int loc_srcBigNum_idx;// [esp+14h] [ebp-2BCCh] int loc_tmp;// [esp+18h] [ebp-2BC8h] int v50;// [esp+18h] [ebp-2BC8h] int loc_gbnidx;// [esp+1Ch] [ebp-2BC4h] signed int loc_ii_0_to_ValSub9;// [esp+20h] [ebp-2BC0h] signed int loc_BitWeightVal;// [esp+24h] [ebp-2BBCh] int loc_BitWeightVal_var_2BBCa;// [esp+24h] [ebp-2BBCh] myvect*loc_BitWeightVal_var_2BBCb;// [esp+24h] [ebp-2BBCh] int loc_vocidx_0x4F;// [esp+28h] [ebp-2BB8h] myvect*v57;// [esp+28h] [ebp-2BB8h] int v58;// [esp+28h] [ebp-2BB8h] int loc_watch1;// [esp+2Ch] [ebp-2BB4h] int loc_watch1a;// [esp+2Ch] [ebp-2BB4h] signed int loc_watch1b;// [esp+2Ch] [ebp-2BB4h] int loc_watch1c;// [esp+2Ch] [ebp-2BB4h] int loc_keylen;// [esp+30h] [ebp-2BB0h] char v64;// [esp+34h] [ebp-2BACh] int loc_tryl;// [esp+38h] [ebp-2BA8h] int(__cdecl*v66)(int,int,int,int,int,int);// [esp+4Ch] [ebp-2B94h] int*v67;// [esp+50h] [ebp-2B90h] myvect**v68;// [esp+54h] [ebp-2B8Ch] void*v69;// [esp+58h] [ebp-2B88h] myvect**v70;// [esp+5Ch] [ebp-2B84h] myvect loc_vect_V0C;// [esp+68h] [ebp-2B78h] int v72;// [esp+74h] [ebp-2B6Ch] myvect loc_vect_buf510;// [esp+80h] [ebp-2B60h] myvect nlw;// [esp+8Ch] [ebp-2B54h] char loc_keystr[256];// [esp+A8h] [ebp-2B38h] char loc_keyh[256];// [esp+1A8h] [ebp-2A38h] char loc_keyd[256];// [esp+2A8h] [ebp-2938h] char loc_BitNum1[5136];// [esp+3A8h] [ebp-2838h] char loc_BitNum2[5136];// [esp+17B8h] [ebp-1428h] myvect*var_18;// [esp+2BC8h] [ebp-18h] myvect*v81;// [esp+2BCCh] [ebp-14h] int v82;// [esp+2BD0h] [ebp-10h] myvect*v83;// [esp+2BD4h] [ebp-Ch] int*v84;// [esp+2BD8h] [ebp-8h] int v85;// [esp+2BDCh] [ebp-4h] int retaddr;// [esp+2BE0h] [ebp+0h] v85=retaddr; v84=&retaddr; v83=v4; v82=v5; v81=v3; v6=alloca(Hi_stack_alloc((unsigned int)&argc)); v66=sub_4B85B0; v67=dword_4B9D1C; v69=&unk_4B9827; v68=&var_18; v70=&var_18; Hi_esp_check_in(&v64); sub_40C510(); Hi_set_debuginfo_sub_40299C(4096); Hi_ecx_BitNum_ClockRandBitWeight(loc_BitNum1); Hi_ecx_BitNum_ClockRandBitWeight(loc_BitNum2); loc_tryl=2; Hi_like_scanf_key(&Hi_input_io,loc_keystr); for(loc_keylen=0;;++loc_keylen) { v8=loc_keylen; if(!loc_keystr[loc_keylen]) break; } v9=0; LOBYTE(v3)=55; while(v9!=loc_keylen) { LOBYTE(v8)=loc_keystr[v9]; LOBYTE(v7)=48; if((char)v8>57) { LOBYTE(v7)=61; if((char)v8<'a' ) v7=v3; } v10=v8-(_DWORD)v7; loc_keyh[v9]=v10; v8=v10-1; if((unsigned __int8)v8>0xEu) goto LABEL_61; ++v9; } v11=loc_keyd; v12=(myvect*)loc_keyh; loc_keyh[loc_keylen]=0; while(loc_keylen) { v13=&loc_keyh[loc_keylen]; do { v14=(unsigned __int8)*v13%0xAu; *v13=(unsigned __int8)*v13/0xAu; *(v13---1)+=16*v14; } while(loc_keyh!=v13); v15=loc_keyh[0]%0xAu; loc_keyh[0]/=0xAu; *v11=v15; do { v4=(myvect*)loc_keylen; v16=loc_keylen-1; if(loc_keyh[loc_keylen-1]) break; --loc_keylen; } while(v16); ++v11; } loc_tryl=2; Hi_BitNum_ctor_P1bytes_P2Radix(&Hi_BigNum1_hbytes,16); v81=(myvect*)Hi_BitNum_ctor_P1bytes_P2Radix(&Hi_BigNum2_hbytes,16); Hi_ecx_BitNum_eq_ECX_mul_P1(loc_BitNum2); Hi_ecx_BitNum_radix_0Ah_to_10h(loc_BitNum1,v4); loc_vect_V0C.first=0; loc_vect_V0C.last=0; loc_vect_V0C.tail=0; loc_keydidx=0; loc_gbnidx=0; loc_srcBigNum_idx=0; loc_vocidx_0x4F=0; while(1) { loc_tryl=3; if(loc_srcBigNum_idx>=Hi_ecx_BitNum_get_BitCnt(loc_BitNum1)) break; loc_BitWeightVal=Hi_ecx_BitNum_get_BitWeightVal(loc_srcBigNum_idx); loc_vect_buf510.last=0; v17=Hi_malloc(0x510); v18=(myvect*)(v17+0x510); v19=v17; loc_vect_buf510.first=v17; v20=0; loc_vect_buf510.tail=(DWORD)v18; do { *(_DWORD*)(v19+v20)=0; v20+=4; } while(v20!=0x510); loc_vect_buf510.last=(DWORD)v18; if(loc_BitWeightVal) { if(loc_BitWeightVal<=9) { v30=loc_vocidx_0x4F; *(_DWORD*)(v19+4*v30)=1; *(_DWORD*)(v19+4*(loc_BitWeightVal+9*(unsigned __int64)(v30/9)+80))=1; v4=(myvect*)3; *(_DWORD*)(v19+4*(loc_BitWeightVal+9*(loc_vocidx_0x4F%9)+161))=1; v12=(myvect*)loc_BitWeightVal; *(_DWORD*)(v19+4*(loc_BitWeightVal+9*(3*(loc_vocidx_0x4F/27)+loc_vocidx_0x4F%9/3)+242))=1; loc_tryl=4; Hi_ecx_vect_0C_add_EleVect0Ch(&loc_vect_buf510); loc_tmp=loc_gbnidx+1; v81=(myvect*)Hi_ecx_BitNum_set_P1BitWeightIdx_P2value(loc_gbnidx,loc_BitWeightVal); var_18=v81; ++loc_vocidx_0x4F; } else { for(loc_ii_0_to_ValSub9=0;;++loc_ii_0_to_ValSub9) { loc_tmp=loc_ii_0_to_ValSub9+loc_gbnidx; loc_watch1=loc_ii_0_to_ValSub9+loc_vocidx_0x4F; if(loc_ii_0_to_ValSub9>=loc_BitWeightVal-9) break; v81=(myvect*)(unsigned __int8)loc_keyd[loc_keydidx+loc_ii_0_to_ValSub9]; loc_tryl=4; Hi_ecx_BitNum_set_P1BitWeightIdx_P2value(loc_tmp,v81); v81=(myvect*)loc_ii_0_to_ValSub9; var_18=(myvect*)loc_ii_0_to_ValSub9; loc_off1=4*loc_watch1; v21=9*(loc_watch1/9); v50=36*(loc_watch1/9)+0x144; v44=36*(loc_watch1/9)+0x168; v45=4*(9*(loc_watch1%9)-v21); loc_watch1a=4*(9*(loc_watch1%9/3+3*(loc_watch1/27))-v21); do { nlw.last=0; loc_tryl=4; v22=Hi_malloc(1296); nlw.first=v22; v23=0; nlw.tail=v22+1296; do { *(_DWORD*)(v22+v23)=0; v23+=4; } while(v23!=1296); v4=(myvect*)v50; nlw.last=v22+1296; *(_DWORD*)(v22+loc_off1)=1; *(_DWORD*)(v22+v50)=1; *(_DWORD*)(v50+v22+v45+324)=1; *(_DWORD*)(v50+loc_watch1a+v22+648)=1; loc_tryl=5; Hi_ecx_vect_0C_add_EleVect0Ch(&nlw); Hi_vect_release(&nlw,v24,v25); v50+=4; v12=(myvect*)v50; } while(v44!=v50); } loc_tryl=4; v26=Hi_ecx_BitNum_get_BitWeightVal(loc_srcBigNum_idx+1); var_18=v18; if(v26<=9) { loc_keydidx+=loc_ii_0_to_ValSub9; loc_vocidx_0x4F+=loc_ii_0_to_ValSub9; } else { v57=NULL; loc_BitWeightVal_var_2BBCa=0; do { v27=anti_debug_funcarray_off_4BC020[loc_BitWeightVal_var_2BBCa]; loc_tryl=4; v57=(myvect*)((char*)v57+((unsigned int)((int(__cdecl*)(myvect*))v27)(var_18)<1)); ++loc_BitWeightVal_var_2BBCa; } while(loc_BitWeightVal_var_2BBCa!=9); v28=loc_vect_buf510.first; v29=loc_watch1; *(_DWORD*)(loc_vect_buf510.first+4*v29)=1; *(_DWORD*)(v28+4*((_DWORD)v57+9*(unsigned __int64)(v29/9)+80))=1; v4=(myvect*)3; *(_DWORD*)(v28+4*((_DWORD)v57+9*(loc_watch1%9)+161))=1; v12=v57; *(_DWORD*)(v28+4*((_DWORD)v57+9*(3*(loc_watch1/27)+loc_watch1%9/3)+242))=1; loc_tryl=4; var_18=(myvect*)Hi_ecx_vect_0C_add_EleVect0Ch(&loc_vect_buf510); loc_vocidx_0x4F=loc_watch1+1; loc_keydidx+=loc_ii_0_to_ValSub9; } } } else { loc_tmp=loc_gbnidx; } Hi_vect_release(&loc_vect_buf510,v18,var_18); ++loc_srcBigNum_idx; loc_gbnidx=loc_tmp; } Hi_ecx_00h_vectV0C_eq_dowith_P1vectV0C_P2cnt_P3_0x144( &loc_vect_V0C, -1431655765*((signed int)(loc_vect_V0C.last-loc_vect_V0C.first)>>2), 324); loc_tryl=6; v31=sub_402DB6(0); var_18=v4; if(v31) { loc_tryl=6; Hi_myvect_ecx_ctor_P1((myvect*)((char*)&nlw+4)); var_18=v12; v58=0; loc_BitWeightVal_var_2BBCb=NULL; do { var_18=(myvect*)(loc_vect_V0C.first+12*(*(DWORD*)((char*)&loc_BitWeightVal_var_2BBCb->first+v72)-1)); loc_tryl=8; Hi_myvect_ecx_ctor_P1(var_18); var_18=loc_BitWeightVal_var_2BBCb; v32=(myvect*)loc_vect_buf510.first; loc_watch1b=0; do { if(*(_DWORD*)(loc_vect_buf510.first+4*loc_watch1b)==1) break; ++loc_watch1b; } while(loc_watch1b!=81); if(loc_watch1b==40) { --v58; } else { loc_watch1c=loc_watch1b-(loc_watch1b>=41); v33=0; do { if(*(_DWORD*)(loc_vect_buf510.first+4*v33+324)==1) break; ++v33; } while(v33!=81); v34=v33%9+1; loc_tryl=7; Hi_ecx_BitNum_get_BitWeightVal(loc_watch1c); v35=(unsigned __int8*)off_4BC060; v36=Hi_ecx_BitNum_get_BitWeightVal(loc_watch1c); var_18=v32; v58+=v34==v35[v36]; } Hi_vect_release(&loc_vect_buf510,v32,var_18); loc_BitWeightVal_var_2BBCb=(myvect*)((char*)loc_BitWeightVal_var_2BBCb+4); } while(loc_BitWeightVal_var_2BBCb!=(myvect*)324); v37=off_4BC05C; v38=0; do { v39=(unsigned __int8)v37[v38]; loc_keylen+=9*(v39^v58)^0x37; v40=v39^v58; v37[v38]=v39^v58; if(v58==v39) break; ++v38; } while(v38!=513); if(loc_keylen==7962) { loc_tryl=8; v41=sub_4B3F00(&dword_4BD9A0,(char*)off_4BC05C); sub_4B0DB0(v41); } Hi_vect_release(&v72,v40,var_18); } j_free(nlw.first); Hi_vect_release(&nlw.last,v42,var_18); sub_402966(&loc_vect_V0C); LABEL_61: sub_401570(loc_BitNum2); sub_401570(loc_BitNum1); Hi_esp_check_out(&v64); return 0; }
0x02 随机位权大数的规整
随机位权大数的内存布局如
BigNum{ .00 vft .04hww.BitCnt .08h.RandBitWeightSeq ww[0x400]&0xFF [::-1] .408h.BitExp2BitWeightPosTbl ww[0x400] cbSize:0x1000 // BitPos orgin = 0,1,2,...,0x3FF orgin[0,1,2,...,0x3FF] = orgin[rand_s(clock_rand)] .1408hww clock_rand .140Chww clock_rand }
大数的多项式表示,表示为不同基数幂与系数的乘积和
BigNum{ .00 vft .04hww.BitCnt .08h.RandBitWeightSeq ww[0x400]&0xFF [::-1] .408h.BitExp2BitWeightPosTbl ww[0x400] cbSize:0x1000 // BitPos orgin = 0,1,2,...,0x3FF orgin[0,1,2,...,0x3FF] = orgin[rand_s(clock_rand)] .1408hww clock_rand .140Chww clock_rand }
大数的多项式表示,表示为不同基数幂与系数的乘积和
BigNum = sum(xi*R^^i) // i = 0 .. n, R=16,10,ect.
BigNum = sum(xi*R^^i) // i = 0 .. n, R=16,10,ect.
大数位权的随机化,会使得我们对BigNum修改起来比较麻烦,这时候我们可以采取规整的方式。
BigNum.08h.RandBitWeightSeq[0x100] 放的是xi值,其位权由BigNum.408h.BitExp2BitWeightPosTb[0x100]索引到该值的索引决定
要针对性修改 xi*R^^i项,需要通过 xi =
RandBitWeightSeq [BitExp2BitWeightPosTb[i]]的方式定位
要进行规整,方便我们直接修改BigNum,我们可以在BigNum基本初始化后(都是随机位权),或赋值前,
修改
RandBitWeightSeq 和 BitExp2BitWeightPosTb,主要是
BitExp2BitWeightPosTb,因为基本初始化后,或赋值前,
RandBitWeightSeq值没有意义
可以直接清了,这里以xdbg32调试器为例,如图,
在上图 4B8FDB,和 4B9001 下断,然后修改ecx指向的BigNum内存布局,.04到.404的内存我们选定,右键binary > Fill 00进行全部填充零除了,
.408开始的0x400个字节,我们先用python生成要复制的内容,然后选定
右键binary > Paste粘贴即可
之后加载的BigNum其各个位权的值都是按顺序排列,可以直接修改
''.join([struct.pack("<L",i).encode('hex') for i in range(0,0x400)])
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-3-28 08:56
被HHHso编辑
,原因:
赞赏记录
参与人
雪币
留言
时间
一笑人间万事
为你点赞~
2022-7-27 01:46
心游尘世外
为你点赞~
2022-7-26 23:39
飘零丶
为你点赞~
2022-7-17 03:22
赞赏
他的文章
- [原创] KCTF 2022 Win. 第六题 约束与伪随机 6745
- [原创] KCTF 2021 Win. 第二题 排排坐 21174
- [原创] KCTF 2021 Win. 第一题 算力与攻击模式 4118
- 鸿蒙通识 26029
- [原创] KCTF 2021 Spr. 第二题 未选择的路 9249
看原图
赞赏
雪币:
留言: