看txt文件,是找到 Serial 是 76876-77776 时的 Name
用ida打开,全是乱码,没有看到有用的字符串
用od打开,找到了correct和wrong
01091CD0 . 56 push esi ; Position.<ModuleEntryPoint>
01091CD1 . 8BF1 mov esi,ecx ; Position.<ModuleEntryPoint>
01091CD3 . 56 push esi ; Position.<ModuleEntryPoint>
01091CD4 . E8 67FAFFFF call Position.01091740
01091CD9 . 8D8E BC000000 lea ecx,dword ptr ds:[esi+0xBC]
01091CDF . 85C0 test eax,eax
01091CE1 . 74 0D je short Position.01091CF0
01091CE3 . 68 F4370901 push Position.010937F4 ; Correct!
01091CE8 . FF15 70320901 call dword ptr ds:[<&mfc100u.#12951>] ; mfc100u.#12951
01091CEE . 5E pop esi ; kernel32.74F88484
01091CEF . C3 retn
01091CF0 > 68 08380901 push Position.01093808 ; Wrong
01091CF5 . FF15 70320901 call dword ptr ds:[<&mfc100u.#12951>] ; mfc100u.#12951
01091CFB . 5E pop esi ; kernel32.74F88484
在ida中找到对应的函数
void __thiscall sub_401CD0(void *this)
{
void *v1; // esi@1
signed int v2; // eax@1
CWnd *v3; // ecx@1
v1 = this;
v2 = sub_401740((int)this);
v3 = (CWnd *)((char *)v1 + 188);
if ( v2 )
CWnd::SetWindowTextW(v3, L"Correct!");
else
CWnd::SetWindowTextW(v3, L"Wrong");
}
只要v2==1即correct,所以看v2,即看sub_401740,很长
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v61);// name
v1 = 0;
v64 = 0;
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v62);// serial
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v63);
LOBYTE(v64) = 2;
CWnd::GetWindowTextW(a1 + 304, &v61); // 将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内
if ( *(_DWORD *)(v61 - 12) == 4 ) // 长度为4
{
v4 = 0;
while ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v4) >= 0x61u
&& (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v4) <= 0x7Au )// 把CString对象里的字符串中的第一个字符ASCII 值送返回来
{
if ( ++v4 >= 4 ) // 四个都为字母
{
LABEL_8:
v5 = 0;
while ( 1 )
{
if ( v1 != v5 )
{
v6 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v5);
if ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v1) == v6 )// 每个字母不相同
goto LABEL_2;
}
if ( ++v5 >= 4 )
{
if ( ++v1 < 4 )
goto LABEL_8;
CWnd::GetWindowTextW(a1 + 420, &v62);
if ( *(_DWORD *)(v62 - 12) != 11 || (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 5) != 45 )// serial长度为11,第六个字符为-
goto LABEL_2;
v7 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, 0);// 第一个字母,第三个字母也是相同的操作
v8 = (v7 & 1) + 5;
v59 = ((v7 >> 4) & 1) + 5;
v53 = ((v7 >> 1) & 1) + 5;
v55 = ((v7 >> 2) & 1) + 5;
v57 = ((v7 >> 3) & 1) + 5; // 取前五位二进制。每一位加5
v9 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, 1);// 第二个字母,第四个字母也是相同的操作
v45 = (v9 & 1) + 1;
v51 = ((v9 >> 4) & 1) + 1;
v47 = ((v9 >> 1) & 1) + 1;
v10 = ((v9 >> 2) & 1) + 1;
v49 = ((v9 >> 3) & 1) + 1; // 取前五位二进制,每一位加1
v11 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
itow_s(v8 + v10, v11, 0xAu, 10); // v8+v10放到v11 第三位
v12 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
v13 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 0);
v2 = &v63;
if ( v13 == v12 )
{
ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
v14 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
itow_s(v57 + v49, v14, 0xAu, 10); // v57+v49放到v14中 第四位
v15 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 1);
v16 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
v2 = &v63;
if ( v15 == v16 )
{
ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
v17 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
itow_s(v53 + v51, v17, 0xAu, 10);// v53+v51放到v17 第五位
v18 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 2);
v19 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
v2 = &v63;
if ( v18 == v19 )
{
ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
v20 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
itow_s(v55 + v45, v20, 0xAu, 10);// v55+v45放到v20中 第一位
v21 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 3);
v22 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
v2 = &v63;
if ( v21 == v22 )
{
ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
v23 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
itow_s(v59 + v47, v23, 0xAu, 10);// v59+v47放到v23中 第二位
Name到Serial一共经过了3步变换:
1.取前五位ASCII并加常数5/1
2.改变顺序(逆序后将第五位放至第二位)
3.分别取两个字母的特定位置数相加逐步逆向: 0 4 2 3 1
3 4 1 0 2
每一位都经过+1和+5,所以和其实为10210-11110
提示中说了最后一个字母是’p’,处理后为00100
故第二位和是11010,位置变换后是01101,换成十进制是13,即m。
然后就看10210的可能情况有哪些,第二位为0,第三位为1,第五位为0。
所以第一位字母和第三个字母必然为x01y0
如果为第一个字符,则x01y0,x1y00,00y1x
如果为第三个字符,则y10x0,y0x01,10x0y
两个x和两个y,只能一个为1,一个为0
所以 00010 10101,00011 10100,00110 10001,00111 10000
即
bump
ctmp
gpmp
dqmp
不能重复所以第三个不可能。提交试一下bump正确