title | date | tags |
---|---|---|
RCTF Reverse wp |
2019-05-20 14:31:06 -0700 |
然后我们看看sub_555555555180
这个函数将input视为4个dword的数,然后xxtea decrypt,且解密后的字符串最后一字节要<4,至于xxtea的识别的话,可以发现它用了常数0x9E3779B9,这是标准tea家族的算法需要用的参数,然后参考这个博客:https://www.jianshu.com/p/4272e0805da3 可以发现是xxtea解密 后面再经过一个check后要输出Bingo!可以发现的是,最后一轮check并不会改变输入的值,且我们只有密文的最后两位是未知的,然后hint又给了md5,那么最后一轮就没有逆的必要了,直接爆破一下
import xxtea
import hashlib;
def decrypt(text,key):
return xxtea.decrypt(text, key,padding=False);
def encrypt(text,key):
return xxtea.encrypt(text, key,padding=False);
key = [0xc7,0xe0,0xc7,0xe0,0xd7,0xd3,0xf1,0xc6,0xd3,0xc6,0xd3,0xc6,0xce,0xd2,0xd0,0xc4]
key = ''.join( [ chr(i) for i in key ] );
cipher = [0x55,0x7e,0x79,0x70,0x78,0x36,0,0];
for i in range(0xff):
print i;
for j in range(4):
cipher[6]=i;
cipher[7]=j;
t = encrypt( ''.join( [ chr(k) for k in cipher ] ) , key);
t = t.encode('hex');
t = "rctf{" + t + "}"
# print i,j,t;
# print hashlib.md5(t).hexdigest()
if ( hashlib.md5(t).hexdigest()=="5f8243a662cf71bf31d2b2602638dc1d" ):
print 'get!!!!!!!!!!!!!!!!!!!';
print t;
# rctf{05e8a376e4e0446e}
和第一题同样用了xxtea,程序的大致逻辑为: 用account作为xxtea的密钥来加密一串常量,得到s1 用password进行一些变换后来索引data的值来构造一个字符串s2 将s2每位^0xcc后解密s1,如果解密的结果最后一位<4就get flag 且可以发现的是第一次加密的常量最后一位<4,那么构造account==s2^0xcc就完事了
from pwn import *
from LibcSearcher import *
s = lambda data : p.send(data);
sl = lambda data : p.sendline(data);
sla = lambda st,data : p.sendlineafter(st,data);
sa = lambda st,data : p.sendafter(st,data);
context.log_level = 'DEBUG';
p = remote("139.180.215.222 ",20000);
sa("account:","2"*16);
sa("password:","1"*16 );
sa("data:",("1"*36+chr(ord('2')^0xcc)+'23456').encode('hex') );
p.interactive();
#rctf{f8b1644ac14529df029ac52b7b762493}
开头有ZwSetInformationThread的反调试,全部patch掉即可,然后伪随机数生成以一串key,来初始化Blowfish,然后中间那一大段就是Blowfish的解密过程,但是我试了一下,好像不太对,应该是作者魔改了某些地方。 然后这一坨东西呢,唯一的作用就是生成了dword_4053A8这个表 这里就是根据dword_4053A8和一些判断来check,可以直接跑dfs出答案
dword_4053A8 = [1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L]
b = [0x61,0x64,0x73,0x77,0]
v32 = 10;
v33 = 0;
v34 = 5;
v35 = 160;
def get(x):
global v32;
global v33;
global v34;
global v35;
if (x==0x61):
v34-=1;
if (x==0x64):
v34+=1;
if (x==0x73):
v32+=1;
v35+=16;
if (x==0x77):
v32-=1;
v35-=16;
def recover(x):
global v32;
global v33;
global v34;
global v35;
if (x==0x61):
v34+=1;
if (x==0x64):
v34-=1;
if (x==0x73):
v32-=1;
v35-=16;
if (x==0x77):
v32+=1;
v35+=16;
ans = [0]*16;
def dfs(x):
global v32;
global v33;
global v34;
global v35;
if x==16:
if v32==4 and v34==9:
print ans;
return ;
else :
return;
for j in b:
get(j);
ans[x] = j;
if dword_4053A8[v35+v34]!=1:
dfs(x+1);
recover(j);
return ;
dfs(0);
可以发现只有唯一一组解:[100, 100, 100, 100, 119, 119, 119, 97, 97, 97, 119, 119, 119, 100, 100, 100]得到加密后的结果之后,就得逆那个Blowfish,由于不知道作者魔改了什么地方,因此我只好自己手动求逆了
key_table= [3240133568, 1745476834, 3452267107, 1321242865, 569233882, 3262172914, 804074711, 2212451896, 3586228949, 3213295876, 2580307897, 3987242710, 844129917, 1301868125, 523187267, 1271787320, 262594588, 3722290984]
t4= [1168098725, 2143783412, 4223038891, 1704033917, 4178117343, 2945735415, 2825925850, 984339604, 1347289438, 3379452791, 2950156119, 706300085, 2079515055, 3901781485, 1544402374, 1821426675, 964568285, 640552008, 3956850450, 2755243166, 2031907515, 3070714208, 2857655890, 2102784284, 3920471734, 854250901, 3377212180, 772521375, 2594285057, 3492744029, 3496582406, 379910604, 715823675, 889661758, 2197166286, 3627040218, 1577891714, 448933615, 1585445108, 651099139, 3453991848, 1440220712, 3589020230, 503375121, 2605120622, 766633696, 3420427157, 3758830553, 1514394895, 1149100097, 3314441272, 392380734, 2146022983, 3279622066, 664973447, 2151131230, 4102023780, 1495959855, 3970793087, 2288701691, 397755879, 3216559517, 1376189164, 542819151, 3104910152, 2405749767, 2809052207, 596389997, 1456573191, 3829548159, 3232675679, 2373640154, 965160193, 119831272, 1507578100, 2556119792, 166344885, 2618311825, 991124589, 3332274264, 3864011504, 3650371572, 2864635658, 3060274353, 529691152, 2573327619, 1271777319, 3138706847, 1090397379, 1535108757, 3006462300, 106062563, 690394157, 2656302998, 2109712965, 895185133, 1731066469, 3319207344, 3632611597, 1575647286, 3588917906, 4048427626, 2687153021, 4125900358, 2603432773, 2757592921, 1448520725, 1157633287, 3502916757, 1553664666, 3124874266, 1533768082, 1532691094, 3949123576, 1675645624, 1585407514, 368398002, 851185089, 1971292865, 1073800266, 1283211117, 55661271, 2987762426, 3975738403, 915042043, 3070614815, 2968127444, 3067898825, 939128145, 4189483066, 2081598105, 2821610633, 3299596625, 196233538, 1359400436, 3523922719, 184983585, 4117896236, 3698158157, 3021399515, 85601795, 3860448152, 1508024952, 1974338817, 870280733, 2136968989, 3551567354, 1557067860, 893032273, 684586179, 4203011978, 3078174710, 2313090574, 4010822195, 1940501298, 2730055892, 3086032814, 2869966891, 1627719627, 3259584178, 951115916, 3025920593, 3066638925, 1352753683, 3775898380, 3767492005, 573526823, 4088679428, 25309037, 3968670459, 242731251, 3108688370, 2126611659, 2401513628, 1808721103, 3610985943, 1233063117, 833018996, 863411547, 3506089372, 2468641806, 4019754552, 1670654455, 880482394, 2875600467, 2914342962, 1175367371, 1291798887, 848834884, 3195838314, 1701996815, 3064221382, 694903403, 1870965766, 2752549238, 157904288, 3473007930, 2731100083, 83984401, 1010966808, 3233003772, 2538451726, 1823469952, 1590711295, 1971753531, 3515536009, 1792922770, 404559177, 2237993770, 297102535, 4261826159, 3979145152, 2288118223, 903764367, 408073404, 1582885367, 3253466358, 6953576, 3600223568, 2484419868, 3281074992, 2177687519, 1272588463, 3833487095, 2663127689, 1073584667, 3873971332, 1469889920, 1410129440, 1023660102, 3003895873, 457689185, 2972622075, 3951685652, 3644263139, 2148037494, 1708348684, 1850530743, 593311568, 2578691134, 956279763, 1976089738, 4277797105, 3717168952, 1121711727, 1617675952, 3490489497, 4139520376, 2244134589, 771093573, 1807084305, 2150072411, 4268407501, 2810357191, 2784343050, 2889821349]
t3= [999458947, 2840872075, 4253128538, 1505629274, 3465559242, 1668080121, 4055444940, 723869178, 4065148034, 958080279, 64385243, 1566772696, 1356142027, 3524983235, 3375040717, 2438445484, 3038662684, 908595932, 3191266251, 1823740184, 1640654677, 3833055798, 3017647716, 107371798, 1535375916, 4101601360, 282467100, 3626746452, 400074080, 3263297189, 3963283496, 688243236, 3573433626, 1131695339, 1581731484, 1956379341, 3495224614, 372016397, 1923552489, 4266044432, 881310725, 747301443, 2654941176, 789470243, 3555165384, 2384517509, 1034477385, 1672301395, 2090547576, 1340944206, 623644060, 1522646203, 3022469935, 116523164, 1516099825, 1509386464, 2891024405, 730820927, 721232517, 176703789, 1882813627, 3860774472, 3956636883, 4030511392, 2954164309, 1086000396, 4206820952, 686150028, 147817751, 540242606, 3746340108, 2352509476, 2450782757, 467952434, 3924359711, 3306358103, 4251134849, 3608379055, 3514113017, 516797453, 80981190, 993805516, 309293254, 2920601822, 153393771, 2388664450, 2498481531, 2481610865, 2278235396, 3834365885, 1854319435, 1935873278, 1326285210, 1783603934, 4062726451, 802524919, 504988478, 1219126007, 1251840797, 2193288125, 582753006, 3761135252, 1994664814, 555129659, 2017529372, 913128891, 4156009595, 1544745628, 1311185893, 1269471927, 656719624, 1227539087, 112004963, 3983222909, 3988568648, 864323452, 3971727408, 3090037546, 2450918012, 4063786179, 1978157191, 1780549588, 2869012200, 1915927972, 564112685, 3759544202, 1643257865, 1481682957, 3332370290, 2039516263, 396367675, 3271108012, 1443568769, 2918398404, 954310584, 3827128213, 3459926913, 2132094283, 1260620796, 83645842, 1415949371, 944095127, 2790840818, 1206396007, 2556793801, 294764747, 343720076, 1231238830, 3940932234, 2107650149, 12009757, 581667797, 1017799359, 2958562355, 1943878139, 1587472515, 3105504536, 2771070234, 92488549, 530503346, 2906347803, 2614884387, 1745337859, 68482897, 4285590561, 4272979130, 74879166, 1614711795, 382909504, 1461851887, 1677691980, 2006523086, 917651469, 2574761391, 80306719, 3279798283, 2630376626, 3319799774, 762667133, 2700433115, 3380569316, 3044652548, 2445500198, 565152823, 3074672637, 318471960, 2287089653, 465554539, 1545593921, 3220150074, 3964040901, 1246219365, 2535377134, 991802423, 1556660147, 3069855685, 4175742361, 1197307755, 4056615286, 2747771186, 3348773252, 139449172, 3672520843, 2443641656, 2278174953, 1571548968, 518293893, 3179261695, 1140931615, 1460661976, 2092051665, 137434968, 1521868011, 4254513336, 2819416099, 817607069, 993255514, 3345259806, 1078215311, 4261818569, 4132833037, 809110109, 380004531, 2880484366, 1253872160, 1614328959, 1909407242, 4234795686, 4238984528, 390233578, 1305360019, 593604673, 3503082768, 791088559, 881827936, 293064256, 1885759158, 3274300151, 3821838357, 3604568431, 2999029469, 634118867, 3248940669, 3650313463, 3822655576, 4288339597, 1324875737, 2864331945, 2323848013, 535907222, 2557004134, 2475597106, 1108787140, 1897525473, 1496201144, 1272438652]
t2= [1581739157, 51808369, 3956889304, 4208884419, 3848448025, 3867915447, 19522000, 3204164685, 207198130, 1357871386, 11366677, 3225220829, 4170130141, 962261641, 755525913, 1689863004, 1028543423, 653082426, 1942827430, 1663814313, 2375897409, 3156268520, 2091011907, 246288043, 2714918590, 3329116811, 4023562335, 3931373662, 3150631548, 599029726, 3886871279, 3662001899, 2729154324, 3802781924, 4148641751, 3080617186, 2971390967, 1268226320, 1792781610, 3258721226, 1454921979, 2369625464, 1449914146, 4156843148, 655250690, 3574936417, 3026585034, 4041895477, 613065169, 933823719, 4190374392, 3352750151, 2645808734, 4004382295, 3981121256, 2871469892, 2322174298, 2884924123, 1125887848, 1566204913, 1512314388, 2799524188, 1647802967, 773497774, 3335073518, 1653573207, 1158401298, 435491684, 350576839, 2759522811, 513504737, 633779133, 3994242186, 3984041905, 2744894823, 1648977434, 2984370793, 3572423222, 1391586072, 2017114380, 1327014325, 1669965070, 1096351494, 680347642, 1609380093, 117633006, 763233406, 969544042, 342157934, 3960956701, 2185631536, 3667469094, 2727394418, 4266512865, 2081758584, 2305765285, 2081700461, 4005238013, 127818202, 3033201238, 3138441506, 211883724, 1536966108, 1543570830, 2950425620, 2575128308, 1532860682, 1417045186, 791612980, 1045910613, 294507393, 3588044607, 3486879631, 3716420803, 719200816, 2075717335, 2102888997, 3599993037, 1717633575, 2395019797, 2179016929, 2831693406, 4045037168, 1366268809, 1469736706, 2185576120, 1060794654, 2746939071, 2795626731, 3544043783, 3384040861, 3581700795, 1888818736, 228947184, 2352368671, 26107321, 2714063227, 2046756435, 1080088233, 2578559425, 197813111, 4165289650, 816209425, 678379439, 365910834, 564418558, 456651362, 1622659838, 1085948280, 3060840483, 2566150808, 1611837431, 3059742993, 3940264446, 2215500969, 2341252970, 3073596438, 2706921143, 4060441620, 1960583635, 774300692, 324096296, 2750041116, 371799919, 2652539836, 1952185142, 1009272904, 550962542, 2483614736, 4075758245, 717803471, 2947726462, 3115530292, 2732829627, 2197250236, 2693620031, 3650332636, 60339225, 4144458054, 3515392806, 1433071693, 3132888447, 459130223, 4047687268, 2376277040, 1205022704, 3309454893, 3049375222, 2866877036, 2746802198, 1263601267, 1860717759, 2272434838, 4176095162, 527594841, 2967969175, 2506583882, 2862829986, 1987889751, 1626598428, 1190556538, 1024906215, 762573523, 3693168756, 699665445, 425327086, 3335111902, 3979619432, 1282175052, 3000481243, 2899225244, 3498842872, 2204855536, 784678227, 3848548257, 2229939482, 400549049, 3618849317, 3587585847, 1313735856, 3478507368, 3567835917, 201403542, 940927203, 2453054736, 2778883247, 2763617289, 3587557579, 4166760152, 2954362173, 781258132, 1887293920, 1402173565, 3597299836, 3029084014, 1206471758, 1701679317, 3158725961, 3377190310, 476098476, 1016766620, 1040036405, 992067988, 1468517874, 892530845, 1273290422, 1152207864, 3010103613, 2182921785, 548868522, 2012401408, 2352986250, 3233395048, 1562663209, 3084245755, 2241695529]
t1= [3663171729, 911774258, 3887613842, 2027978519, 922359206, 4030889631, 1900045864, 4204480388, 4066726742, 2572764396, 1132213885, 3687704155, 1806192213, 814548910, 1034192571, 81927033, 1826692187, 384645237, 2285592762, 4218603743, 1242066459, 2647121943, 4175044955, 224155416, 1755703130, 2450378793, 2346432339, 1379879247, 4144203808, 2400664671, 3887710211, 169302619, 2017340623, 3462423906, 1952482000, 4125407667, 2369774452, 950243129, 2911026141, 2949874610, 7941397, 219741600, 1967208727, 3428903339, 1688942330, 461115147, 2206273410, 352928426, 1583695642, 3251256276, 695496005, 165339256, 689559208, 963586597, 1399475516, 1469951354, 3418439549, 2675624569, 2749577945, 1146475711, 2649968942, 3903716058, 522766084, 784131185, 2915554322, 1576252257, 3619299568, 3683171765, 81457698, 2564273294, 529533915, 3276457257, 4248798809, 314704615, 2538042805, 2769411191, 1508758912, 4137291957, 2045415450, 1692341316, 1724364187, 3958443186, 1989966633, 3853478897, 2712901839, 3781461160, 3077980480, 4043416405, 936529367, 2091524617, 4220464913, 3869012497, 310448968, 3236555358, 3079823288, 1015597062, 22661604, 3323357598, 2899708722, 3004030490, 3745075582, 3107843633, 1854281115, 3277941089, 3066598229, 313182521, 912571443, 1172618694, 3782319463, 1379947978, 2822363371, 1374291117, 2795820038, 2911384291, 3397724215, 3779241699, 2711879894, 4197807181, 3203523684, 2574994168, 1832927868, 3213456595, 967350007, 3450664525, 2754511066, 3829799730, 3433891191, 3633702845, 2109417050, 1703224920, 3450220510, 4207961758, 1262281550, 3764157555, 3633433948, 1338288715, 220055184, 1472130429, 3708379934, 1571542665, 3550161240, 1917063696, 3622417128, 2813813477, 76871199, 1403380566, 4153903186, 3005526816, 334768409, 2851585657, 1148008167, 2823051392, 471639810, 331525282, 3943067092, 2022822364, 1705863251, 3017214304, 2339349191, 3324347350, 1524173975, 874763011, 3269541863, 3529891441, 3945900664, 1971507167, 69722993, 1984518770, 1262990659, 1987187180, 1592554971, 3154280867, 822132442, 2616278834, 1176859007, 286110282, 240504336, 4110135951, 2339709565, 3285875338, 3089549967, 1569546645, 3758265480, 2290111941, 2015298426, 3388295274, 3455213785, 3425744399, 1147294988, 1754005818, 2588202802, 2956499508, 1622831670, 4269116791, 3757565594, 4128610149, 2186146208, 1983174412, 3373180463, 1611348889, 2289010006, 3328946070, 1390641839, 1933355737, 2610090149, 3484674506, 3943356698, 3624761359, 966557941, 3701338534, 832444852, 2114785138, 63726701, 1880780916, 1382277205, 2768075570, 2626342455, 3897817381, 1330400384, 1934634614, 873489634, 3992558968, 2128185270, 3283142600, 682499024, 2276789125, 2967664765, 2841130920, 2222490643, 2775342329, 3018510310, 673248417, 3331382344, 1673573056, 187143399, 2201764151, 2860484536, 3387172141, 2890243279, 1467169887, 3091071890, 1694169074, 3979028612, 2364158037, 3363530688, 3801008915, 71344238, 672550490, 4113546307, 3276258784, 2806397645, 1180242014, 4234728569, 227098560, 3450504956, 490211951]
def f(x):
a1 = x&0xff;
a2 = (x&0xff00)>>8;
a3 = (x&0xff0000)>>16;
a4 = (x&0xff000000)>>24;
return t1[a1]+( t2[a2]^(t3[a3]+t4[a4]) );
def decrypt(xl,xr):
v10 = 17;
i = 0;
for i in range(16):
xl = xl ^ key_table[v10];
v10-=1;
temp = xl;
xl = xr ^ f(xl);
xr = temp;
xl &=0xffffffff;
xr &=0xffffffff;
# print i,hex(xl),hex(xr),v10;
xr^=key_table[0];
xl^=key_table[1];
return hex(xr),hex(xl);
def encrypt(xl,xr):
v10 = 2;
i = 0;
xr^=key_table[0];
xl^=key_table[1];
for i in range(16):
pre_xl = xr ^ key_table[v10];
v10+=1;
xr = f(xr)^xl;
xl = pre_xl;
xl &=0xffffffff;
xr &=0xffffffff;
# print i,hex(xl),hex(xr),v10;
return hex(xl),hex(xr);
a = "64646464777777616161777777646464"
ans = ""
for i in range(0,len(a),16):
a1 = int(a[i:i+8],16);
a2 = int(a[i+8:i+16],16);
a1,a2 = encrypt(a2, a1);
ans +=a1[2:-1];
ans +=a2[2:-1];
print ans,len(ans);
# RCTF{db824ef8605c5235b4bbacfa2ff8e087}
限制程序输入的前512位只能是0 or 1,然后会根据你的输入来解密一个函数,但由于最后的函数是未知的,因此直接求逆不可能,但程序限制了v27,也就是根据输入取解密后的值x,然后v27-=x,最后要求v27==0,乍一看这只能爆破,但其实猜想一下要使程序能用非爆破的方式求解的话,v27很可能是一个特殊的数字,例如最大值,最小值,如果这么一想,那这其实就是一个在矩阵里按照特殊规则取数,然后求最大值的问题,那么这其实就是非常一个简单的dp问题f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j]
贴一下脚本,写的很急,很丑,且因为担心有多解,还加了一些判断
#include<iostream>
using namespace std;
unsigned long long f[1111][1111];
unsigned long long a[1111][1111];
unsigned long long t=0;
int num=0;
struct ha{
int v[20];
int num;
};
ha c[1111][1111];
void get(int x,int y){
if (x<1||y<1){
cout<<"!!!!!!!!!!!!!!!wrong case! "<<x<<" "<<y<<endl;
return ;
}
if (x==1&&y==1){
cout<<"0";
return;
}
if (x==1&&y==2){
cout<<"1";
return ;
}
if (c[x][y].num>1) {
cout<<x<<" "<<y<<endl;
cout<<"not just one answer"<<c[x][y].num<<endl;
}
if ( c[x][y].v[0]==1 ){
get(x-1,y-1);
cout<<"1";
}
else {
get(x-1,y);
cout<<"0";
}
}
int main(){
freopen("func.mem","r",stdin);
for (int i=1;i<=0x200;i++){
for (int j=1;j<=0x200;j++){
scanf("%lld",&a[i][j]);
// cin>>a[i][j];
//cout<<hex<<a[i][j]<<endl;
}
}
t = 0;
int i=1;
for (int j=1;j<=0x200;j++){
if (j<=2) i=1;
else i=j-1;
for (;i<=0x200;i++){
f[i][j] = max( f[i-1][j]+a[i][j], f[i-1][j-1]+a[i][j] );
// cout<<hex<<f[i][j]<<endl;
if ( f[i-1][j]+a[i][j] == f[i-1][j-1]+a[i][j] ){
c[i][j].num = 0;
c[i][j].v[ c[i][j].num++ ] = 0;
c[i][j].v[ c[i][j].num++ ] = 1;
continue;
}
if (f[i][j]==f[i-1][j]+a[i][j]){
c[i][j].v[ 0 ] = 0;
c[i][j].num=1;
}
else {
c[i][j].num=1;
c[i][j].v[ 0 ] = 1;
}
t = max(t,f[i][j]);
if (f[i][j]>=0x100758E540F){
get(i,j);cout<<endl;
cout<<"i get one "<<i<<" "<<j<<" "<<hex<<f[i][j]<<endl;
}
}
}
}
可以发现v27的值确实是最大值,且是唯一解 00000000010101000000000111100111111110100111100101001000101010010011101100111101011111111111111111001110111011011000000101110111001111100100011000000000000110001111110100000000001101110111010101011111000101110000011000111001110000000000000000000000011001000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100011111110000100111000000000000000000000000000000010000000000000001000001100000000000000101000000000100000010000000000000000010000000000000000000000 然后我们动态跟一下解密后的函数,发现是个vm
int __stdcall sub_431A020(_DWORD *a1, int a2, int a3)
{
int result; // eax
signed int j; // [esp+D0h] [ebp-28Ch]
signed int i; // [esp+DCh] [ebp-280h]
__int64 v6; // [esp+E8h] [ebp-274h]
int v7; // [esp+F0h] [ebp-26Ch]
int v8; // [esp+F4h] [ebp-268h]
int v9; // [esp+F8h] [ebp-264h]
int v10; // [esp+FCh] [ebp-260h]
int v11; // [esp+100h] [ebp-25Ch]
int v12; // [esp+104h] [ebp-258h]
int v13; // [esp+108h] [ebp-254h]
int v14; // [esp+10Ch] [ebp-250h]
int v15; // [esp+110h] [ebp-24Ch]
int v16; // [esp+114h] [ebp-248h]
int v17; // [esp+118h] [ebp-244h]
int v18; // [esp+11Ch] [ebp-240h]
int v19; // [esp+120h] [ebp-23Ch]
int v20; // [esp+124h] [ebp-238h]
int v21; // [esp+2F0h] [ebp-6Ch]
int v22; // [esp+2FCh] [ebp-60h]
int v23; // [esp+308h] [ebp-54h]
int v24; // [esp+314h] [ebp-48h]
int v25; // [esp+320h] [ebp-3Ch]
int v26; // [esp+32Ch] [ebp-30h]
int v27; // [esp+338h] [ebp-24h]
int v28; // [esp+344h] [ebp-18h]
int v29; // [esp+350h] [ebp-Ch]
v29 = a1[53] + 2 * a1[58];
v28 = a1[55] + 12;
v27 = *(_DWORD *)a1[55];
v26 = *(_DWORD *)(a1[55] + 4);
v25 = *(_DWORD *)(a1[55] + 8);
v24 = v28;
v23 = 0;
v22 = 0;
v21 = 0;
v6 = 0i64;
v7 = 0;
v8 = 0;
v9 = 0;
v10 = 0;
v11 = 0;
v12 = 0;
v13 = v29;
v14 = 0;
v15 = 0;
v16 = v27;
v17 = v26;
v18 = v25;
v19 = v28;
v20 = a2;
while ( 1 )
{
result = v23 + a3;
if ( !*(_BYTE *)(v23 + a3) )
return result;
v21 += (*(char *)(v23 + a3) - 48) << v23 % 6;
result = v23 / 6;
if ( v23 % 6 != 5 )
goto LABEL_76;
switch ( v21 )
{
case 0:
v21 = 0;
for ( i = 0; i < 24; ++i )
v21 += (*(char *)(++v23 + a3) - 48) << i;
LODWORD(v6) = v21;
goto LABEL_75;
case 1:
v21 = 0;
for ( j = 0; j < 24; ++j )
v21 += (*(char *)(++v23 + a3) - 48) << j;
HIDWORD(v6) = v21;
goto LABEL_75;
case 2:
LODWORD(v6) = *(unsigned __int16 *)(v29 + 2 * v22++);
LABEL_75:
v21 = 0;
LABEL_76:
++v23;
break;
case 3:
HIDWORD(v6) = v6;
goto LABEL_75;
case 4:
v8 = v7;
goto LABEL_75;
case 5:
if ( (signed int)v6 < 128 )
*((_DWORD *)&v6 + v6) = HIDWORD(v6);
goto LABEL_75;
case 6:
if ( SHIDWORD(v6) < 128 )
LODWORD(v6) = *((_DWORD *)&v6 + HIDWORD(v6));
goto LABEL_75;
case 7:
if ( v7 < 128 )
*((_DWORD *)&v6 + v7) = v8;
goto LABEL_75;
case 8:
if ( v8 < 128 )
v7 = *((_DWORD *)&v6 + v8);
goto LABEL_75;
case 9:
LODWORD(v6) = *(_DWORD *)(v6 + 4 * HIDWORD(v6));
goto LABEL_75;
case 10:
*(_DWORD *)(v6 + 4 * HIDWORD(v6)) = v9;
goto LABEL_75;
case 11:
LODWORD(v6) = HIDWORD(v6) + v6;
goto LABEL_75;
case 12:
LODWORD(v6) = v6 - HIDWORD(v6);
goto LABEL_75;
case 13:
LODWORD(v6) = HIDWORD(v6) * v6;
goto LABEL_75;
case 14:
LODWORD(v6) = (signed int)v6 / SHIDWORD(v6);
goto LABEL_75;
case 15:
LODWORD(v6) = HIDWORD(v6) & v6;
goto LABEL_75;
case 16:
LODWORD(v6) = HIDWORD(v6) | v6;
goto LABEL_75;
case 17:
LODWORD(v6) = HIDWORD(v6) ^ v6;
goto LABEL_75;
case 18:
LODWORD(v6) = (_DWORD)v6 << SBYTE4(v6);
goto LABEL_75;
case 19:
LODWORD(v6) = (signed int)v6 >> SBYTE4(v6);
goto LABEL_75;
case 20:
LODWORD(v6) = (signed int)v6 > SHIDWORD(v6);
goto LABEL_75;
case 21:
LODWORD(v6) = (signed int)v6 < SHIDWORD(v6);
goto LABEL_75;
case 22:
LODWORD(v6) = v6 == HIDWORD(v6);
goto LABEL_75;
case 23:
LODWORD(v6) = v6 != HIDWORD(v6);
goto LABEL_75;
case 24:
LODWORD(v6) = v23;
goto LABEL_75;
case 25:
v23 = v6;
v21 = 0;
break;
case 26:
if ( (_DWORD)v6 )
goto LABEL_75;
v23 = HIDWORD(v6);
v21 = 0;
break;
default:
return result;
}
}
}
先打印一下日志,看看程序在干啥
#include<stdio.h>
int v7 = 0;
int v8 = 0;
int v9 = 0;
int result;
const char *input="123";
int reg[128];
int vm_ip;
int len=0;
int op;
int i;
int j;
const char *opcode="000000010101100100000000000000110000010000010110100000000011000000000000000000001100110000000000110000000000000000000000101000000000000000000000000000000000110000000000010000000000000000000000101000000000111000000000000000000000110000011000110000111000010010110000000000110000000000000000000000101000000000100000000000000000000000110000000000010000000000000000000000101000000000011000000000000000000000110000011000111000110100110000000000011000000000000000000000101000100000111000000000000000000000011000100000100000000000000000000000110100110000000000111000000000000000000000101000000000000000000000000000000000100110100000011000000000000000000000011000100000111000000000000000000000101100100000111111000100001011110000011010100000011011000011000000000000010110100000011000000000000000000000011000110000000000110000000000000000000000101000000000100000000000000000000000110000000000010000000000000000000000101000100000110100000000000000000000011000111000100010110000000000110100000000000000000000101000100000001100000000000000000000011000111000100010110000000000001100000000000000000000101000100000101100000000000000000000011000111000100010110000000000101100000000000000000000101000000000111000000000000000000000100000000000000000000000000000101000100000101100000000000000000000011000110000000000110000000000000000000000101000000000100000000000000000000000110000000000010000000000000000000000101000100000111000000000000000000000011000111000101010100000011011111001000000000000010110100000011000000000000000000000011000110000000000110000000000000000000000101000000000100000000000000000000000110000000000010000000000000000000000101000100000111000000000000000000000011000111000110100110000000000000010000000000000000000101000100000111000000000000000000000011000110000000000110000000000000000000000101000000000100000000000000000000000110000000000010000000000000000000000101000100000011100000000000000000000011000111000100100110000000000100010000000000000000000101000100000000010000000000000000000011000110000000000110000000000000000000000101000000000100000000000000000000000110000000000010000000000000000000000101000100000100010000000000000000000011000111000100010110000000000001000000000000000000000101000100000111000000000000000000000011000110000000000110000000000000000000000101000000000100000000000000000000000110000000000010000000000000000000000101000100000011100000000000000000000011000111000010100100000111000000000000000000000011000100000100000000000000000000000110100110000000000111000000000000000000000101000000000000001110010000000000000100110100000110100000000000000000000011000110000000000001000000000000000000000101000100000111100000000000000000000011000100000000000000000000000000000010100100000001100000000000000000000011000110000000000001000000000000000000000101000100000111100000000000000000000011000100000100000000000000000000000010100100000101100000000000000000000011000110000000000001000000000000000000000101000100000111100000000000000000000011000100000010000000000000000000000010100100000011100000000000000000000011000110000000000001000000000000000000000101000100000111100000000000000000000011000100000110000000000000000000000010100"+'\0';
int vm_start(){
while ( 1 )
{
int v14[50]={3137482249L, 4278332938L, 4278332939L, 570568204L, 16634354L, 142862L, 142863L, 142864L, 142865L, 142866L, 142867L, 142868L, 142869L, 142870L, 142871L, 142872L, 142873L, 142874L, 142875L, 142876L, 142877L, 142878L, 142879L, 142880L, 142881L, 142882L, 142883L, 142884L, 142885L, 142886L, 142887L, 142888L, 142889L, 142890L, 142891L, 142892L, 142893L, 142894L, 1711418927L, 1996631600L, 2852269617L, 4278332978L, 4278332979L, 142900L, 142901L, 142902L, 142903L, 142904L, 142905L, 1996631610L};
reg[8] = (int)&input;
reg[14] =(int)&v14;
result = opcode[vm_ip];
if ( !opcode[vm_ip] )
return result;
op += (opcode[vm_ip] - '0') << vm_ip % 6;
result = vm_ip / 6;
if ( vm_ip % 6 != 5 )
goto LABEL_76;
printf("%02x ",op);
switch ( op )
{
case 0:
op = 0;
for ( i = 0; i < 24; ++i )
op += (opcode[++vm_ip] - 48) << i;
reg[0] = op;
printf("Mov reg[0] , 0x%x\n",op);
goto LABEL_75;
case 1:
op = 0;
for ( j = 0; j < 24; ++j )
op += (opcode[++vm_ip] - 48) << j;
reg[1] = op;
printf("Mov reg[1] , 0x%x\n",op);
goto LABEL_75;
case 2:
reg[0] = input[len++];
printf("reg[0]=input[%d]\n",len-1);
LABEL_75:
op = 0;
LABEL_76:
++vm_ip;
break;
case 3:
reg[1] = reg[0];
printf("Mov reg[1] , reg[0]\n");
goto LABEL_75;
case 4:
reg[3] = reg[2];
printf("Mov reg[3] , reg[2]\n");
goto LABEL_75;
case 5:
if ( reg[0] < 128 ){
int t = reg[0];
reg[reg[0]] = reg[1];
printf("reg[%d]=reg[1] (0x%x)\n",t,reg[1]);
}
goto LABEL_75;
case 6:
if ( reg[1] < 128 ){
int t = reg[1];
reg[0] = reg[reg[1]];
printf("reg[0]=reg[%d] (0x%x)\n",t,reg[0]);
}
goto LABEL_75;
case 7:
if ( reg[2] < 128 ){
int t = reg[2];
reg[ reg[2] ] = reg[3];
printf("reg[%d]=reg[3] (0x%x)\n",t,reg[3] );
}
goto LABEL_75;
case 8:
if ( reg[3] < 128 ){
int t = reg[3];
reg[2] = reg[ reg[3] ];
printf("reg[2] = reg[%d] (0x%x)\n",t,reg[2] );
}
goto LABEL_75;
case 9:
printf("Mov reg[0] , (reg[0] + 4 * reg[1]) \n");
reg[0] = *(unsigned int *)(reg[0] + 4 * reg[1]);
goto LABEL_75;
case 10:
printf("Mov (reg[0]+4*reg[1]) , v9=0x%x \n",v9);
*(unsigned int *)(reg[0] + 4 * reg[1]) = v9;
goto LABEL_75;
case 11:
reg[0] += reg[1];
printf("Add reg[0] , reg[1]\n");
goto LABEL_75;
case 12:
reg[0] -= reg[1];
printf("Sub reg[0] , reg[1]\n");
goto LABEL_75;
case 13:
reg[0] *= reg[1];
printf("Mul reg[0] , reg[1]\n");
goto LABEL_75;
case 14:
reg[0] /= reg[1];
printf("div reg[0] , reg[1]\n");
goto LABEL_75;
case 15:
reg[0] &= reg[1];
printf("And reg[0] , reg[1]\n");
goto LABEL_75;
case 16:
reg[0] |= reg[1];
printf("Or reg[0] , reg[1]\n");
goto LABEL_75;
case 17:
reg[0] ^= reg[1];
printf("Xor reg[0] , reg[1]\n");
goto LABEL_75;
case 18:
reg[0] <<= (reg[1])&0xff;
printf("Shl reg[0] , 0x%x \n",(reg[1])&0xff);
goto LABEL_75;
case 19:
reg[0] >>= (reg[1])&0xff;
printf("Shr reg[0] , 0x%x \n",(reg[1])&0xff);
goto LABEL_75;
case 20:
reg[0] = reg[0] > reg[1];
printf("reg[0] > reg[1] reg[0]=%d\n",reg[0]);
goto LABEL_75;
case 21:
reg[0] = reg[0] < reg[1];
printf("reg[0] < reg[1] reg[0]=%d\n",reg[0]);
goto LABEL_75;
case 22:
reg[0] = reg[0] == reg[1];
printf("reg[0] == reg[1] reg[0]=%d\n",reg[0]);
goto LABEL_75;
case 23:
reg[0] = reg[0] != reg[1];
printf("reg[0] != reg[1] reg[0]=%d\n",reg[0]);
goto LABEL_75;
case 24:
reg[0] = vm_ip;
printf("reg[0] = vm_ip");
goto LABEL_75;
case 25:
vm_ip = reg[0];
printf("jump %02x\n",vm_ip);
op = 0;
break;
case 26:
if ( reg[0] )
goto LABEL_75;
vm_ip = reg[1];
printf("jump %02x\n",vm_ip);
op = 0;
break;
default:
return result;
}
}
}
int main(){
vm_start();
}
粗略的打印了一下
00 Mov reg[0] , 0x26a
03 Mov reg[1] , reg[0]
02 reg[0]=input[0]
1a 01 Mov reg[1] , 0x30 input[i]-=0x30
0c Sub reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x3
05 reg[3]=reg[1] (0x1)
00 Mov reg[0] , 0x0
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x2
05 reg[2]=reg[1] (0x0)
00 Mov reg[0] , 0x7
03 Mov reg[1] , reg[0]
06 reg[0]=reg[7] (0x0)
03 Mov reg[1] , reg[0]
07 reg[0]=reg[3] (0x1)
12 Shl reg[0] , 0x0 input[i]<<=i;
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x3
05 reg[3]=reg[1] (0x1)
00 Mov reg[0] , 0x1
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x2
05 reg[2]=reg[1] (0x1)
00 Mov reg[0] , 0x6
03 Mov reg[1] , reg[0]
06 reg[0]=reg[6] (0x0)
07 reg[1]=reg[3] (0x1)
0b Add reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x6
05 reg[6]=reg[1] (0x1) reg[6]+=input[i]
01 Mov reg[1] , 0x7
06 reg[0]=reg[7] (0x0)
01 Mov reg[1] , 0x1
0b Add reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x7
05 reg[7]=reg[1] (0x1)
00 Mov reg[0] , 0x0
19 jump 00
00 Mov reg[0] , 0x26a
03 Mov reg[1] , reg[0]
02 reg[0]=input[1]
1a 01 Mov reg[1] , 0x30
0c Sub reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x3
05 reg[3]=reg[1] (0x2)
00 Mov reg[0] , 0x0
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x2
05 reg[2]=reg[1] (0x0)
00 Mov reg[0] , 0x7
03 Mov reg[1] , reg[0]
06 reg[0]=reg[7] (0x1)
03 Mov reg[1] , reg[0]
07 reg[0]=reg[3] (0x2)
12 Shl reg[0] , 0x1
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x3
05 reg[3]=reg[1] (0x4)
00 Mov reg[0] , 0x1
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x2
05 reg[2]=reg[1] (0x1)
00 Mov reg[0] , 0x6
03 Mov reg[1] , reg[0]
06 reg[0]=reg[6] (0x1)
07 reg[1]=reg[3] (0x4)
0b Add reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x6
05 reg[6]=reg[1] (0x5)
01 Mov reg[1] , 0x7
06 reg[0]=reg[7] (0x1)
01 Mov reg[1] , 0x1
0b Add reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x7
05 reg[7]=reg[1] (0x2)
00 Mov reg[0] , 0x0
19 jump 00
00 Mov reg[0] , 0x26a
03 Mov reg[1] , reg[0]
02 reg[0]=input[2]
1a 01 Mov reg[1] , 0x30
0c Sub reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x3
05 reg[3]=reg[1] (0x3)
00 Mov reg[0] , 0x0
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x2
05 reg[2]=reg[1] (0x0)
00 Mov reg[0] , 0x7
03 Mov reg[1] , reg[0]
06 reg[0]=reg[7] (0x2)
03 Mov reg[1] , reg[0]
07 reg[0]=reg[3] (0x3)
12 Shl reg[0] , 0x2
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x3
05 reg[3]=reg[1] (0xc)
00 Mov reg[0] , 0x1
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x2
05 reg[2]=reg[1] (0x1)
00 Mov reg[0] , 0x6
03 Mov reg[1] , reg[0]
06 reg[0]=reg[6] (0x5)
07 reg[1]=reg[3] (0xc)
0b Add reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x6
05 reg[6]=reg[1] (0x11)
01 Mov reg[1] , 0x7
06 reg[0]=reg[7] (0x2)
01 Mov reg[1] , 0x1
0b Add reg[0] , reg[1]
03 Mov reg[1] , reg[0]
00 Mov reg[0] , 0x7
05 reg[7]=reg[1] (0x3)
00 Mov reg[0] , 0x0
19 jump 00
00 Mov reg[0] , 0x26a
03 Mov reg[1] , reg[0]
02 reg[0]=input[3]
1a jump 26a
01 Mov reg[1] , 0x6
06 reg[0]=reg[6] (0x11)
01 Mov reg[1] , 0x7
0d Mul reg[0] , reg[1]
01 Mov reg[1] , 0xf423f
16 reg[0] == reg[1] reg[0]=0 //check
01 Mov reg[1] , 0xc36
1a jump c36
00 Mov reg[0] , 0x928a000
逻辑很简单
input="123"
for i in range(len(input)):
v6+= (ord(input[i])-0x30)<<i
print v6;
print hex(v6);
#V6*7 == 0xf423f
因为长度是未知的,因此我随便找了一个解79889000968999 (注意,答案是分两部分,这是第二部分的) 带到vm里,发现指令数暴增,且由于我这个vm模拟的不全面,还会报错,大致分析了一下后面的功能,可以发现它貌似也在解密什么东西,最主要的是,后面的操作都和input没啥关系,因此直接将第一轮的答案+第二轮带入