在 start 处 sub_140014EB5 ();
可疑
有挺多的反调试:
.text:00007FF7CD3342B5 mov rcx, [rbp+810h+hObject] ; hObject
.text:00007FF7CD3342BC call cs:CloseHandle ; Check Invalid Close->Exception
ida patch 一下
from idc import *
from idautils import *
# patch program
ea = 0x14004E530
eaed = 0x014004E5DF
for i in range(ea, eaed):
# get
byte = get_bytes(i, 1)
byte = (ord(byte) ^ 0x11) - 34
# set
patch_byte(i, byte)
sub_14001458C((_DWORD)Buffer, 64614, v12, v26, 0);
解密
v10 = (const char *)getStr((__int64)aGameData);
Stream = fopen(v10, "rb");
v11 = (const char *)getStr((__int64)aGameTmp);
v25 = fopen(v11, "w");
fread(Buffer, 1ui64, 0xC2DBui64, Stream);
v26 = getStr((__int64)aPowerpowerpo);
v12 = getStr((__int64)aPowerpowerpowe);
sub_14001458C((_DWORD)Buffer, 64614, v12, v26, 0);
看位数判断是哪个参数
&( $sHellid[1] + $ShElLid[13] + 'X')( ( [RuntIme.INteroPsErviCEs.maRSHal]::PTrtostriNGAUTo( [rUNtIme.inteRopServIces.MarshAl]::seCuREsTrinGtobStr( $('76492d1116743f0423413b16050a5345MgB8AG8ARwBQAGMAeQBnAFIAUgBXACsAcAB6AFYALwBFADgAZwA5AGIASwA3AFEAPQA9AHwAYQBkADIAYwAzADYAYwA5ADAAZgA1AGQANwNAAwAGUAZAAwADEAZgBkADQAZQA1ADMANwBjADMANQAwADYAMwA2AGYAZAA0ADQANABlADYAOQBkAGYAZAA3AGQAMwBiADYAMwA2AGYANwA3ADcANQ.....A4AGEAZABhADQANwA4ADQANAA4ADQAOQBmADUANwAwAGUAOABmAGEAOABkADQAOABkADUAMwAwADUAZAA4AGQAYwA5ADcANQAxADUAZAA2AGIAMwA1AGQAMQAwAGQANAA=' | conveRTTo-SECureSTrinG -K (94..117)) ) )))
iex hook 一下
function Invoke-Expression {
$input | % { $_; }
$args | % { $_; }
}
三层套娃展开
function enenenenene {
param(
$plaintextBytes,
$keyBytes
)
# Initialize S and KSA
$S = 0..255
$j = 0
for ($i = 0; $i -lt 256; $i++) {
$j = ($j + $S[$i] + $keyBytes[$i % $keyBytes.Length]) % 256
$temp = $S[$i]
$S[$i] = $S[$j]
$S[$j] = $temp
}
# PRGA and encryption
$i = 0
$j = 0
$ciphertextBytes = @()
for ($k = 0; $k -lt $plaintextBytes.Length; $k++) {
$i = ($i + 1) % 256
$j = ($j + $S[$i]) % 256
$temp = $S[$i]
$S[$i] = $S[$j]
$S[$j] = $temp
$t = ($S[$i] + $S[$j]) % 256
$ciphertextBytes += ($plaintextBytes[$k] -bxor $S[$t])
}
# Return ciphertext as a string
return $ciphertextBytes
}
function enenenenene1 {
param(
$inputbyte
)
$key = @(0x70, 0x6f, 0x77, 0x65, 0x72)
$encryptedText = @();
for ($k = 0; $k -lt $inputbyte.Length; $k++) {
$encryptedText = enenenenene -plaintextBytes $inputbyte -keyBytes $key;
$key = enenenenene -plaintextBytes $key -keyBytes $encryptedText;
}
return $encryptedText + $key;
}
function enenenenene2 {
param(
$inputbyte
)
$key = @(0x70, 0x30, 0x77, 0x65, 0x72)
for ($k = 0; $k -lt $inputbyte.Length; $k++) {
$inputbyte[$k] = $inputbyte[$k] + $key[$k % $key.Length]
}
return $inputbyte;
}
function enenenenene3 {
param(
$inputbyte
)
$key = @(0x70, 0x30, 0x77, 0x33, 0x72)
for ($k = 0; $k -lt $inputbyte.Length; $k++) {
$inputbyte[$k] = $inputbyte[$k] * $key[$k % $key.Length]
}
return $inputbyte;
}
$registryPath = 'HKCU:\Software\PacManX'
$valueName = 'MYFLAG'
$value = Get-ItemPropertyValue $registryPath $valueName
$plaintext = @($value) | ForEach-Object {
$input = $_
$plaintext = @()
for ($i = 0; $i -lt $input.Length; $i++) {
$plaintext += [int][char]$input[$i]
}
$plaintext
}
if ($plaintext.Length -ne 36) {
Set-Content -Path "log.txt" -Value "ERROR"
exit
}
$encrypted1Text = enENenenene2 -inputbyte (enenenENene2 -inputbyte (enenenenene3 -inputbyte (Enenenenene2 -inputbyte (enenenenene2 -inputbyte (enenenenene2 -inputbyte (enenenenene1 -input $plaintext))))))
$result = @(38304, 8928, 43673, 25957 , 67260, 47152, 16656, 62832 , 19480 , 66690, 40432, 15072 , 63427 , 28558 , 54606, 47712 , 18240 , 68187 , 18256, 63954 , 48384, 14784, 60690 , 21724 , 53238 , 64176 , 9888 , 54859 , 23050 , 58368 , 46032 , 15648 , 64260 , 17899 , 52782 , 51968 , 12336 , 69377 , 27844 , 43206 , 63616)
for ($k = 0; $k -lt $result.Length; $k++) {
if ($encrypted1Text[$k] -ne $result[$k]) {
Set-Content -Path "log.txt" -Value "ERROR"
exit
}
Set-Content -Path "log.txt" -Value "RIGHT"
# s = [0x64, 0x80, 0x99, 0x87, 0x88, 0x92, 0x85, 0x96, 0x6F, 0x63,
# 0x92, 0x94, 0x7E, 0x92, 0x81, 0x6B]
# for i in range(len(s)):
# s[i] = (s[i] ^ 0x11)-34
# print(''.join([chr(i) for i in s]))
# # Software\PacManX
# s2 = [0x7E, 0x6A, 0x79, 0x7F, 0x72, 0x78, 0x00, 0x00]
# for i in range(len(s2)):
# s2[i] = (s2[i] ^ 0x11)-34
# print(''.join([chr(i) for i in s2]))
result = [38304, 8928, 43673, 25957, 67260, 47152, 16656, 62832, 19480, 66690, 40432, 15072, 63427, 28558, 54606, 47712, 18240, 68187, 18256, 63954,
48384, 14784, 60690, 21724, 53238, 64176, 9888, 54859, 23050, 58368, 46032, 15648, 64260, 17899, 52782, 51968, 12336, 69377, 27844, 43206, 63616]
def RC4(plaintextBytes, keyBytes):
S = [i for i in range(256)]
j = 0
for i in range(256):
j = (j + S[i] + keyBytes[i % len(keyBytes)]) % 256
temp = S[i]
S[i] = S[j]
S[j] = temp
i = 0
j = 0
ciphertextBytes = []
for k in range(len(plaintextBytes)):
i = (i + 1) % 256
j = (j + S[i]) % 256
temp = S[i]
S[i] = S[j]
S[j] = temp
t = (S[i] + S[j]) % 256
ciphertextBytes.append(plaintextBytes[k] ^ S[t])
return ciphertextBytes
key1 = [0x70, 0x6f, 0x77, 0x65, 0x72]
key2 = [0x70, 0x30, 0x77, 0x65, 0x72]
key3 = [0x70, 0x30, 0x77, 0x33, 0x72]
for i in range(len(result)):
result[i] -= key2[i % len(key2)]
for i in range(len(result)):
result[i] -= key2[i % len(key2)]
for i in range(len(result)):
if result[i] % key3[i % len(key3)] != 0:
print("maybe wrong line 82")
result[i] = result[i]//key3[i % len(key3)]
for i in range(len(result)):
result[i] -= key2[i % len(key2)]
for i in range(len(result)):
result[i] -= key2[i % len(key2)]
for i in range(len(result)):
result[i] -= key2[i % len(key2)]
print(result)
# [4, 40, 8, 202, 246, 83, 201, 169, 75, 241, 23, 168, 174, 253, 135, 88, 234, 214, 51, 217, 94, 162, 151, 119, 123, 235, 60, 102, 145, 168, 73, 180, 181, 44, 119, 126, 111, 224, 239, 35, 230]
# key 是定长的,所以是后5位
cipher = result[0:-5]
key = result[-5:]
# 一直往回循环就行
for i in range(len(cipher)):
key = RC4(key,cipher)
cipher = RC4(cipher,key)
print("".join([chr(i) for i in cipher]))