最近比賽有點多 決定把 脫強殼 還有軟件調試 還有 漏洞戰爭 放一放 先刷一些題目壓壓驚
最終還是選擇了 Jarvis OJ (buuctf 太卡了。。。
以前也寫過幾道 === 希望能把上面的題目刷個80%。。
PWN的以前寫過 到時候拾起來 把那個PWN博客也更一下
然後把我自己以前寫的博客直接粘貼到這上面
以前寫的 這裏就不再說了
Jarvis OJ 軟件密碼破解-1
https://mp.csdn.net/postedit/83514674
Jarvis OJ Classical CrackMe2 C#的動態調試
https://mp.csdn.net/postedit/90770515
FindKey
這個題目沒啥好說的。。
找一個pyc的反編譯網站 看一下 然後把代碼反退一下就出來結果了 。。
Classical Crackme
這個題目就是典型的 C#題目了。。
base64解密一下就ok了
Fibonacci
這個題目我一看就樂了 斐波那契鴨 。。。。
然後後面就自閉了 。。。。
然後拖入ida 發現了很多jar2 的字符串 以前做個類似的題目 但是也沒有做出來 但是知道了 是用java jvm打包成的exe
python的反編譯確實很簡單 但是這個 java的 有些時候確實比較噁心。。。。
這裏參考了夜影師傅的博客。。
https://blog.csdn.net/whklhhhh/article/details/78682279
首先需要一個工具
下載鏈接 https://github.com/slavemaster/e2j
e2j的原理 就是dump 缺點就是 沒有執行的函數dump不出來
這裏就給了這個題目留下了一個坑點
我們先把這個e2j搞起來
在目錄下 執行 set JAVA_TOOL_OPTIONS=-javaagent:e2j-agent.jar 然後運行程序即可
然後 目錄下出現了 一個jar文件
拖入我們發現了很多信息 還沒有來得及開心的時候。。。。。。 發現了 程序邏輯不對勁 我們找不到flag在哪 。。
想了一下 b這個類應該沒有函數 然後就沒有執行 也沒有dump。。。
那麼問題來了。。。。 怎麼去找。。
這裏夜影師傅給了一個鏈接 https://blog.csdn.net/whklhhhh/article/details/78682279
java代碼被存放在RCDATA數據中 我們用 PE explorer 來看
然後找到xdbg 找到這個數據
下硬斷 然後循環開始解
然後把r10指向的內存dump出來
然後 得出 b裏面的數據
然後直接運行hello 這個函數的程序即可
軟件破解2
這個我以前貌似看過夜影巨巨的博客 。。。。。 貌似 把這個題就做出來了====
先不說了 直接開擼 可以看到主函數的內容
可以看到 主函數還對是否爲 參數做了判斷
感覺很好玩
還有一個明顯的int 3斷點
然後去看check 函數
發現了一堆函數, 大概就是創建子進程 然後 寫子進程進行讀內存還有寫內存的操作
那麼 int 3 就是返回一個異常 然後由父進程接收 然後寫/讀
這裏可以看看彙編是什麼樣子的
額 輸入的字符串和我們的
0070D9C0 57 65 6C 63 6F 6D 65 20 74 6F 20 43 46 46 20 74 Welcome to CFF t
0070D9D0 65 73 74 21 est!
進行異或
可以寫出腳本 得出flag
然後下面的一道題就是
文件數據修復
這個題目看起來就花裏胡哨的
不過定位到關鍵點就會發現內在邏輯還是很清楚的
發現了有很多的readfile 的操作 這裏先把邏輯給挑出來
四個字節 驗證文件的驗證碼
四個字節 下個部分的字節長度
上面值的字節數 未知作用
0x10字節 key md5兩次 和這個作比較
然後四個字節 就是讀取後面的所有字節數
然後就是字節數進行解密= ==
這個題 的切入點就是 那個代表後面所有的字節數在哪 如果找到了 那麼文件頭就可以修復的差不多了
可以看出這個題目的切入點就是這
然後看 key的加密算法 是兩次md5 根據前面的爆破 我們可以直接寫腳本把這個值爆破出來 因爲題目上說的是 8位 數字
import hashlib
strr=""
strr=chr(0x48)+chr(0xb1)+chr(0xed)+chr(0x05)+chr(0x8d)+chr(0xf7)
strrs=strr.encode('hex')
print(strr.encode('hex'))
for i in range(10):
print "[*] "+"i:"+str(i)
#exit()
for j in range(10):
for k in range(10):
for ii in range(10):
for jj in range(10):
for kk in range(10):
for iii in range(10):
for jjj in range(10):
flag=str(i)+str(j)+str(k)+str(ii)+str(jj)+str(kk)+str(iii)+str(jjj)
flags=(hashlib.md5(hashlib.md5(flag.encode(encoding='UTF-8')).digest()).hexdigest())
#print(flags[-12:])
#exit()
if flags[-12:]==strrs:
print(flags)
print(flag)
exit()
print("gg")
key求出來是 20160610 然後把值輸入上去 那個 0x11是通過中間字符個數算的
然後發現
額 然後 試了試輸入中間的值
額 中間的值 就是輸出的文件名,,
然後用wps打開有了flag
軟件破解 3
這個題目就是比較好玩的一道題目了
先看一下程序邏輯。
一開始是確定按鈕是不可以點擊的, 然後隨便輸入了一些字符 發現確定鍵可以了 一激動還以爲自己輸入對了flag 結果只是長度輸入正確了
拖入ida 分析一波
點進去看一眼
我還以爲這個是隻算 00 01 這算兩個長度 而不是一個長度,,,, 結果我想錯了
OD動態調試了一下 還是0x10 那麼 這裏就很矛盾,,,
再看出flag的地方
發現了一個盲點,
那就是
想有確定按鈕就必須有 長度16的地方,,, 但是長度16有到不了這個正確的窗口 ,,,
但是根據我前幾天的做windows pwn題的感覺 已經 以前寫的一道花指令的題目 這個題目應該是有了異常機制
但是在調用堆棧裏 沒有發現SHE 。。。。 這就很尷尬了,,然後昨天晚上感覺這個異常應該是會對這個數據處理的
然後就做了一個硬件斷點 和驚喜的發現斷下了 ,
在ida 裏面找到 這個地方
然後交叉引用
發現瞭如下的東西 。。
這個方程組很好解決 z3一把梭
那麼問題就出在了 怎麼去日那個加密函數,
這個表就是 AES 生成s盒的表,,,
然後看了一下 然後搜了一些 然後去逆s盒就ok
下面寫出腳本 這裏的腳本就下面的參考帖子的腳本寫的,,,
import hashlib
from z3 import *
re_table = [0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D]
def decrypt(c):
result = b''
for i in c:
a = i // 0x10
b = i % 0x10
result += re_table[a * 0x10 + b].to_bytes(1, "little")
return result
l = [Int("l%d"%i) for i in range(8)]
s = Solver()
s.add((l[3] + l[2] + l[1] + l[0] )%256 == 71)
s.add((l[7] + l[6] + l[5])%256 == 3)
s.add(l[0]%256 == l[1] + 68)
s.add(l[1]%256 == l[2] + 2)
s.add(l[2]%256 == l[3] - 59)
s.add(l[6]%256 == l[4] + 10)
s.add(l[6]%256 == l[7] + 9)
s.add(l[4]%256 == l[5] + 52)
for i in l:
s.add(i>=0)
s.add(i<256)
while(s.check()==sat):
c = b''
m = s.model()
for i in range(8):
c +=(((m[l[i]].as_long()).to_bytes(1, 'little')))
# 輸出方程的解
#print(c)
for i in c:
print(hex(i)[2:].zfill(2).upper(), end='')
print('\t', end='')
# 查表
for i in range(64*4):
p = decrypt(c)
c = p
# 輸出flag
for i in c:
print(hex(i)[2:].zfill(2).upper(), end='')
# 排除該解後繼續求解
s.add(l[0] != m[l[0]].as_long())
print("\n")
參考鏈接
https://www.52pojie.cn/thread-674056-1-1.html
這裏帖子講的很明白 具體異常的調用過程 可以參考一下
病毒分析
這個題挺難的,,, 我感覺分析了一些東西 但是沒有分析完全 這裏也寫一下把
這裏的 反調試很好玩,,
用的是 NtQueryInformationProces 查找父進程的pid 然後對比
下面就是socket的傳輸了
遍歷文件夾等 然後遇到docx 開始傳輸==
然後裏面的算法看的不是很清楚,。。
這裏把靜態的字符串恢復腳本安排了 有空 把這個題安排了,。。
import hashlib
from z3 import *
filename=(0x3410350F).to_bytes(4, 'little')
filename+=(0x8383324).to_bytes(4, 'little')
filename+=(0x332E272F).to_bytes(4, 'little')
filename+=(0x2835202C).to_bytes(4, 'little')
filename+=(0x33112F2E).to_bytes(4, 'little')
filename+=(0x3224222E).to_bytes(4, 'little')
filename+=(0x41).to_bytes(4, 'little')
str(filename, encoding = "utf-8")
flag=""
for i in range(len(filename)):
flag+=chr(filename[i]^0x41)
print(flag)
ModuleName=0x4135412F.to_bytes(4, 'little')
ModuleName+=0x412D4125.to_bytes(4, 'little')
ModuleName+=0x4141412D.to_bytes(4, 'little')
out_put=""
for i in range(len(ModuleName)):
out_put+=chr(filename[i]^0x41)
print(out_put)
out_str=""
l=[27,99,6,12,53,51,58,48,23,18,62,16,29,22,18,2,5,90,88,55,47,57,40,65,21,9,23]
for i in range(len(l)):
out_str+=chr(l[i]^(0x58+i))
print(out_str)
'''
#include<idc.idc>
static main()
{
auto i,j,form,end;
form=0x40AB90;
end=0x40ABC6;
for(i=form;i<end;i=i+2)
{
Message("%d,",Byte(i));
}
Message("\n"+"OK\n");
}
'''
然後就是 APK_500
這個題目就很好玩了,,
我是直接脫入so 開始分析的,,
先說一下我本來的腳本。。
baby=[0x85,0x8B,0xEC,0x83,0x6c,0x9c,0x83,0x8d,0xc,0x1,0x75,0x5f,0xc6,0x45,0xf3,0x50]
cmps="ddedd4ea2e7bef168491a6cae2bc660"
#print(len(baby))
#print(len(cmps))
cmpint=[]
for i in range(0,32,2):
cmpint.append(int("0x"+cmps[i:i+2],16))
#print(cmpint)
#print(len(baby))
for i in range(len(baby)):
baby[i]=baby[i]^cmpint[i]
ppx=baby[-7:]+baby[:-7]
print(ppx)
for i in range(4):
baby[i]=baby[i]-1
for i in range(len(baby)):
baby[i]=baby[i]^i
for i in range(len(baby)):
print(chr(baby[i]),end="")
'''
#include<idc.idc>
static main()
{
auto i,j,form,end;
form=0x2c87;
end=0x2ca7;
for(i=form;i<end;i=i+1)
{
Message("%c",Byte(i)^(57+i-0x2c87));
}
Message("\n"+"OK\n");
}
'''
然後跑出一堆亂碼 然後
我就自閉了,,,
看了一下夜影師傅的博客 才知道了怎麼回事= =
先說一下這個題目是幹啥的,
然後有一點就是 交叉引用
這個因爲喫過虧 所以就 認識的比較,,,清楚
然後其實上面的腳本問題我也是喫過虧 但是還是沒有長記性 == 是我太菜了,,
引用夜影師傅的原話
ddedd4ea2e7bef168491a6cae2bc660
腳本調用bytes.fromhex的時候發現它長度不對,只有31位
轉十六進制的時候是sprintf(buff, “%x”, input),注意格式化不是%02x
因此有一個0被消掉了,需要爆破
so 。。。。
只能爆破嘍
babys=[0x85,0x8B,0xEC,0x83,0x6c,0x9c,0x83,0x8d,0xc,0x1,0x75,0x5f,0xc6,0x45,0xf3,0x50]
cmps="ddedd4ea2e7bef168491a6cae2bc660"
n=[]
for i in range(32):
st=cmps[:i]+"0"+cmps[i:]
n.append(bytes.fromhex(st))
#print(len(baby))
#print(len(cmps))
cmpint=[]
for i in range(0,32,2):
cmpint.append(int("0x"+cmps[i:i+2],16))
for cmpint in n:
baby=babys
flag=[]
#print(cmpint)
#print(len(baby))
for i in range(len(baby)):
flag.append(((cmpint[i]^baby[i])))
flags=""
flag=flag[-7:]+flag[:-7]
#print(ppx)
#print(flag)
for i in range(4):
flag[i] =flag[i] - 1
for i in range(len(flag)):
flag[i]=flag[i]^i
if (flag[i]<=32 or flag[i]>=127):
break
flags+=chr(flag[i])
else:
print(flags)
Broken Drivers
這個題目就。。。
一開始我打開的時候發現是這樣子的,,
emmmmm 這樣不會炸麼 只有creat 和close 的派遣函數 。,。
在裏面也木有發現什麼有用的信息,, 試着安裝一下 結果不行,,,
問了一下一個搞驅動開發的老哥 ,,, 然後用loadpe 修復了一下
然後在彙編窗口發現了有個unload的派遣函數
這個是我已經修復好的,
但是發現被標紅了 而且 ida f5 裏面也發現了 不正確的反彙編
emmmm 這好像有點尷尬 , 想了好久沒有想出來原因。最後感覺是重定位表的問題 因爲 ida 分析出來的是 絕對地址,, 但是不知道怎麼改 ,, 看了這篇看雪的帖子 恍然大悟 https://bbs.pediy.com/thread-223239.htm
和我一開始的想法一樣 就是 地址是絕對值 並不是相對的地址 然後不會被重定位表給重定位
那麼 我們需要修復一下重定位表
改成1193 然後我們把這個題目PE-checksum 用 Stud_PE_chs 改一下
然後 驅動終於加載了,,,
那麼用ida 看一下程序邏輯
發現在creat的派遣函數裏面
申請了一部分的空間 然後進入了 一個加密函數
然後看卸載函數 發現了
emmmm 動態來一波
因爲需要creat 的派遣函數 所以我們寫一個r3程序
但是我的一直返回錯誤是5 訪問拒絕 現在還不知道怎麼回事 等到get到了補上這個題目的題解
後記:
我太垃圾了 這個題目 還有一個判斷就是
讓程序的pid 的判斷是 等於 0x168 不然的話 就返回錯誤碼 。。。。。。。。。。。。。。
這個地方沒有注意 我真的是太垃圾了。。
然後 nop 或者動態把這個判斷過了 然後斷下unload
拿到flag
然後就是這個DD - Evil Exe
ddctf的原題 應該是 ,,
這個題目其實就是一個esp的殼 脫完之後然後ida裏面邏輯就很清楚
上面的一個函數就是變成docx的
然後其中邏輯都很簡明,,
把這個題目然後直接
寫一個腳本 拿到了 字符串
然後寫了一個腳本直接拿到flag
stst="hcomXhing.hchuxhdidihade@hd9e9h7173hd4aehd69bhb1c4hadachc49bhTF-ch DDChKey:"
flag=""
for i in range(14,-1,-1):
flag+=stst[i*5+1:i*5+5]
print(flag)
後面的x是多餘的
爬樓梯
這個題比較可惜 反編譯不通過 xopsed也沒有寫出來 然後FindPass用C語言寫的出問題了。。。。
我先說一下 反編譯沒有通過這個題 這個 大家可能都遇到了 本來我是想有個騷操作的 就是xopsed 但是我遇到了一個問題
那就是 這裏面的類變量確實沒有經過函數傳遞 這個 我就不知道怎麼做了 我知道是通過this 指針傳遞的。。。。
然後確實比較可惜 沒有能夠解決掉 要是 有 函數傳遞 或者是 返回值 我應該是能搞定的 可惜沒有搞定。。。
然後我就只能看 別人的博客了
我們需要反編譯 把unknown 整個文件夾給刪除了就好了 就可以 反編譯了
至於 是改的地方
我們可以把按鈕變成 ture 就可以了 這個還是比較簡單的
把181那個v5 改成1 就可以了
第二題 就更坑爹了 我用的c語言讀取 竟然不行 後面全是 0 搞得我很頭大 一直也沒有解決 上面兩個問題 要是有那個大佬解決了 還希望能夠指點一二 然後 我就去翻了一下別人的博客 發現了 這樣的一篇博客 (看別人的博客上面說 動態調試也可以 我還是分析了一下算法。。)
參考鏈接
https://blog.csdn.net/qq_35078631/article/details/78222249
所以 我還是用python了 python真的好用。。(我C語言太菜了000)
那個 eq_str 是根據 編號的出來的
#_*_coding:utf-8_*_
imgsrc="src.jpg"
eq_str = "Tr43Fla92Ch4n93"
imarr=[]
fp=open(imgsrc,"rb")
fp.seek(0,0)
for i in range(1024):
b=fp.read(1)
imarr.append(ord(b))
flag=""
for i in range(len(eq_str)):
if imarr[ord(eq_str[i])]<128:
temp=imarr[ord(eq_str[i])]%10
else:
temp=(-(imarr[ord(eq_str[i])]%128))%10
if i%2==0:
flag+=chr(ord(eq_str[i])-temp)
else:
flag+=chr(ord(eq_str[i])+temp)
print(flag)
得出flag
另外附上一張 動態調試得到的flag。。。。。。。
smail 這個題 比較可惜 畢竟自己也不怎看smail 直接 就是java 代碼直接擼 但是我從來不否認 smail 的用處 所以
我就來看了看 果然 。。。。。 不過我將smail 複製進了 smail 裏面 一步一步的分析
因爲本人的smail 也不是很好 如果有錯誤 還請指教 謝謝
.method public constructor <init>()V
.locals 1
.prologue
.line 22
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
.line 21
const-string v0, "cGhyYWNrICBjdGYgMjAxNg==" #將這個字符串給v0
iput-object v0, p0, Lnet/bluelotus/tomorrow/easyandroid/Crackme;->str2:Ljava/lang/String;
.line 23
const-string v0, "sSNnx1UKbYrA1+MOrdtDTA=="
invoke-direct {p0, v0}, Lnet/bluelotus/tomorrow/easyandroid/Crackme;->GetFlag(Ljava/lang/String;)Ljava/lang/String;
.line 24
return-void
.end method
這裏 p0->str2 是 cGhyYWNrICBjdGYgMjAxNg== 而 "sSNnx1UKbYrA1+MOrdtDTA== 爲 參數 傳進了函數裏面
const/4 v3, 0x0
.line 27
invoke-virtual {p1}, Ljava/lang/String;->getBytes()[B
move-result-object v2
invoke-static {v2, v3}, Landroid/util/Base64;->decode([BI)[B
#"sSNnx1UKbYrA1+MOrdtDTA=="
move-result-object v0
.line 29
.local v0, "content":[B
new-instance v1, Ljava/lang/String;
iget-object v2, p0, Lnet/bluelotus/tomorrow/easyandroid/Crackme;->str2:Ljava/lang/String;
invoke-virtual {v2}, Ljava/lang/String;->getBytes()[B
move-result-object v2
invoke-static {v2, v3}, Landroid/util/Base64;->decode([BI)[B #"cGhyYWNrICBjdGYgMjAxNg=="
move-result-object v2
這裏是將 兩個字符串 給 base64 解密了
invoke-direct {v1, v2}, Ljava/lang/String;-><init>([B)V
.line 30
.local v1, "kk":Ljava/lang/String;
sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream;
#decrypt("cGhyYWNrICBjdGYgMjAxNg==")
invoke-direct {p0, v0, v1}, Lnet/bluelotus/tomorrow/easyandroid/Crackme;->decrypt([BLjava/lang/String;)Ljava/lang/String;
move-result-object v3
#v3->(v2) v2="sSNnx1UKbYrA1+MOrdtDTA==" v3=decrypt
invoke-virtual {v2, v3}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
.line 31
const/4 v2, 0x0
這裏面就是 cGhyYWNrICBjdGYgMjAxNg==' base64 後 的字符串 被當成參數傳進去 看後面應該是 AES/ECB/NoPadding
那麼就可以的出來 寫一個python腳本 跑出來
#coding:utf-8
import base64
from Crypto.Cipher import AES
if __name__=='__main__':
str1=base64.b64decode('cGhyYWNrICBjdGYgMjAxNg==')
str2=base64.b64decode('sSNnx1UKbYrA1+MOrdtDTA==')
aes=AES.new(str1,AES.MODE_ECB)
print(aes.decrypt(str2))
然後第三題
DD - Hello
我還以爲這個題 是安卓題 畢竟ddctf 結果 確實 不是 哈哈啊哈
這個題 很簡單 隨便找了一下 函數 發現了這個函數 試着 逆向了一下算法
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int start=0x100000CB0;
int sub=0x100000C90;
char byte_100001040[]={0x41,0x10,0x11,0x11,0x1b,0x0a,0x64,0x67,0x6a,0x68,0x62,0x68,0x6e,0x67,0x68,0x6b,0x62,0x3d,0x65,0x6a,0x6a,0x3d,0x68,0x04,0x05,0x08,0x03,0x02,0x02,0x55,0x08,0x5d,0x61,0x55,0x0a,0x5f,0x0d,0x5d,0x61,0x32,0x17,0x1d,0x19,0x1f,0x18,0x20,0x04,0x02,0x12,0x16,0x1e,0x54,0x20,0x13,0x14};
int main()
{
int s=((start - sub) >> 2) ^ byte_100001040[0];
for(int i=0;i<55;i++){
byte_100001040[i]-=2;
byte_100001040[i]^=s;
s++;
}
printf("%s\n",byte_100001040+1);
return 0;
}
第四題
DD - Android Easy 這個題也很簡單
照着寫一下就行
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
char p[] = { -40, -62, 107, 66, -126, 103, -56, 77, 122, -107, -24, -127, 72, -63, -98, 64, -24, -5, -49, -26, 79, -70, -26, -81, 120, 25, 111, -100, -23, -9, 122, -35, 66, -50, -116, 3, -72, 102, -45, -85, 0, 126, -34, 62, 83, -34, 48, -111, 61, -9, -51, 114, 20, 81, -126, -18, 27, -115, -76, -116, -48, -118, -10, -102, -106, 113, -104, 98, -109, 74, 48, 47, -100, -88, 121, 22, -63, -32, -20, -41, -27, -20, -118, 100, -76, 70, -49, -39, -27, -106, -13, -108, 115, -87, -1, -22, -53, 21, -100, 124, -95, -40, 62, -69, 29, 56, -53, 85, -48, 25, 37, -78, 11, -110, -24, -120, -82, 6, -94, -101 };
char q[] = { -57, -90, 53, -71, -117, 98, 62, 98, 101, -96, 36, 110, 77, -83, -121, 2, -48, 94, -106, -56, -49, -80, -1, 83, 75, 66, -44, 74, 2, -36, -42, -103, 6, -115, -40, 69, -107, 85, -78, -49, 54, 78, -26, 15, 98, -70, 8, -90, 94, -61, -84, 64, 112, 51, -29, -34, 126, -21, -126, -71, -31, -24, -60, -2, -81, 66, -84, 85, -91, 10, 84, 70, -8, -63, 26, 126, -76, -104, -123, -71, -126, -62, -23, 11, -39, 70, 14, 59, -101, -39, -124, 91, -109, 102, -49, 21, 105, 0, 37, -128, -57, 117, 110, -115, -86, 56, 25, -46, -55, 7, -125, 109, 76, 104, -15, 82, -53, 18, -28, -24 };
char arrayOfByte2[100];
char arrayOfByte1[100];
int main()
{
int i,j=0;
//printf("%d\n",strlen(p));
for (i = 0; i <120; i++) {
arrayOfByte2[i] =(p[i] ^ q[i]);
//printf("%d ",arrayOfByte2[i]);
}
int k = arrayOfByte2[0];
for (i = 0; arrayOfByte2[(k + i)] != 0; i++) {}
while (j < i)
{
arrayOfByte1[j] = arrayOfByte2[(k + j)];
j++;
}
printf("%s\n",arrayOfByte1);
return 0;
}
DD - Android Normal 這個題 是魔鬼嗎。。。。
讓我分析so庫也就算了 還是 。。。。。 emm 反正看起來很頭暈 但是感覺動態調試能夠一把過 然後就來了一波動態調試 效果還不錯
v1的值 就是答案
[61dctf]stheasy 這個題麼.....
挺簡單的
代碼邏輯在裏面 只需要 寫一個腳本就可以了 ida 導出數據 shift+e 是真的好用。。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
char str[]="lk2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U";
int num[100]={72,93, 141, 36, 132, 39, 153, 159, 84, 24, 30, 105,126,51, 21, 114, 141, 51, 36, 99, 33, 84, 12, 120, 120, 120, 120, 120, 27};
int main()
{
for(int i=0;i<29;i++)
printf("%c",str[int(num[i]/3)-2]);
return 0;
}
androideasy
這個題 就更可惜了
下面是腳本
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int s[100] = { 113, 123, 118, 112, 108, 94, 99, 72, 38, 68, 72, 87, 89, 72, 36, 118, 100, 78, 72, 87, 121, 83, 101, 39, 62, 94, 62, 38, 107, 115, 106 };
int main()
{
for(int i=0;s[i]!=0;i++)
{
printf("%c",s[i]^0x17);
}
printf("\n");
return 0;
}
參考鏈接
https://blog.csdn.net/whklhhhh/article/details/78682279