能力值:
( LV2,RANK:10 )
2 楼
signed int genSeed(DWORD *seed, DWORD cellx, WORD cell4, WORD cell6)
{
signed int result; // eax@21
if ( cellx & 0x80000000 )
{
if ( cellx & 0x40000000 )
{
seed[3] = (cellx >> 16) & 0x3FFF;
seed[4] = (unsigned __int16)cellx;
seed[2] = seed[3] | 0xC000;
seed[2] = (unsigned __int16)(((unsigned __int16)seed[2] << 15) | (seed[2] >> 1));
seed[2] = (seed[2] ^ (seed[2] >> 15)) & 1 | seed[2] & 0xFFFE;
if ( !(seed[3] & 0xF) )
seed[3] |= 0x10u;
if ( !(seed[3] & 0x1E0) )
seed[3] |= 0x200u;
if ( !(seed[3] & 0x3C00) )
seed[3] |= 0x4000u;
if ( seed[4] & 0x8000 )
seed[3] |= 0x4000u;
seed[3] = 4 * seed[3] | 3;
if ( !(seed[4] & 0xF) )
seed[4] |= 0x10u;
if ( !(seed[4] & 0x1E0) )
seed[4] |= 0x200u;
if ( !(seed[4] & 0x3C00) )
seed[4] |= 0x4000u;
seed[4] = seed[4] & 0x7FFF ^ 1;
seed[1] = 4 * cell6 | 3;
*seed = 1;
}
else
{
seed[1] = cell4 | (cell4 << 16) | 0xC000;
seed[3] = cellx & 0x3FFF3FFF | 0xC000;
if ( seed[3] & 1 )
seed[3] |= 0x40000000u;
*seed = 0;
}
result = 0;
}
else
{
result = 1;
}
return result;
}
int FnAlgorithm(DWORD *seed, unsigned int data)
{
DWORD v2; // ecx@4
DWORD v3; // ecx@4
DWORD v4; // ecx@28
DWORD v5; // ecx@28
signed int l; // [sp+4h] [bp-1Ch]@39
signed int k; // [sp+8h] [bp-18h]@34
signed int j; // [sp+10h] [bp-10h]@9
signed int i; // [sp+14h] [bp-Ch]@2
int v11; // [sp+1Ch] [bp-4h]@1
unsigned int v12; // [sp+2Ch] [bp+Ch]@9
unsigned int v13; // [sp+2Ch] [bp+Ch]@39
v11 = 0;
if ( *seed )
{
for ( i = 31; i >= 0; --i )
{
seed[1] ^= (data >> i) & 1;
v2 = (seed[1] << 17) | (seed[1] >> 1);
seed[1] = v2 & 0x3FFFF;
v3 = seed[1];
if ( v3 & 0x20000 )
seed[1] ^= seed[3];
seed[2] ^= 1u;
seed[2] = (unsigned __int16)(((unsigned __int16)seed[2] << 15) | (seed[2] >> 1));
if ( seed[2] & 0x8000 )
seed[2] ^= seed[4];
}
v12 = (data << 16) | (data >> 16);
for ( j = 31; j >= 0; --j )
{
switch ( (seed[1] >> 4) & 8 | (seed[1] >> 3) & 4 | (seed[1] >> 12) & 2 | (seed[1] >> 17) & 1 )
{
case 6u:
v11 |= ((seed[2] ^ (seed[2] >> 15)) & 1) << j;
break;
case 3u:
v11 |= ((seed[2] >> 1) & 1) << j;
break;
case 4u:
v11 |= ((seed[2] >> 2) & 1) << j;
break;
case 0xAu:
v11 |= ((seed[2] >> 3) & 1) << j;
break;
case 7u:
v11 |= ((seed[2] >> 4) & 1) << j;
break;
case 0xFu:
v11 |= ((seed[2] >> 5) & 1) << j;
break;
case 2u:
v11 |= ((seed[2] >> 6) & 1) << j;
break;
case 0u:
v11 |= ((seed[2] >> 7) & 1) << j;
break;
case 0xDu:
v11 |= ((seed[2] >> 8) & 1) << j;
break;
case 5u:
v11 |= ((seed[2] >> 9) & 1) << j;
break;
case 9u:
v11 |= ((seed[2] >> 10) & 1) << j;
break;
case 1u:
v11 |= ((seed[2] >> 11) & 1) << j;
break;
case 0xCu:
v11 |= ((seed[2] >> 12) & 1) << j;
break;
case 0xEu:
v11 |= ((seed[2] >> 13) & 1) << j;
break;
case 8u:
v11 |= ((seed[2] >> 14) & 1) << j;
break;
case 0xBu:
v11 |= ((seed[2] >> 15) & 1) << j;
break;
default:
break;
}
seed[1] ^= (v12 >> j) & 1;
v4 = (seed[1] << 17) | (seed[1] >> 1);
seed[1] = v4 & 0x3FFFF;
v5 = seed[1];
if ( v5 & 0x20000 )
seed[1] ^= seed[3];
seed[2] ^= 1u;
seed[2] = (unsigned __int16)(((unsigned __int16)seed[2] << 15) | (seed[2] >> 1));
if ( seed[2] & 0x8000 )
seed[2] ^= seed[4];
}
}
else
{
for ( k = 31; k >= 0; --k )
{
seed[1] ^= (data >> k) & 1;
seed[1] = (seed[1] << 31) | (seed[1] >> 1);
if ( seed[1] & 0x80000000 )
seed[1] ^= seed[3];
}
v13 = (data << 16) | (data >> 16);
for ( l = 31; l >= 0; --l )
{
v11 |= (seed[1] & 1) << l;
seed[1] ^= (v13 >> l) & 1;
seed[1] = (seed[1] << 31) | (seed[1] >> 1);
if ( seed[1] & 0x80000000 )
seed[1] ^= seed[3];
}
}
return v11;
}
signed int sproQuery(DWORD *InOutBuff, int len, DWORD Cellx, WORD Cell4, WORD Cell6)
{
signed int dst; // eax@1
int v; // eax@4
int i; // [sp+0h] [bp-20h]@2
DWORD seed[5]; // [sp+4h] [bp-1Ch]@1
unsigned int src; // [sp+18h] [bp-8h]@4
int t; // [sp+1Ch] [bp-4h]@4
dst = genSeed(seed, Cellx, Cell4, Cell6);
if ( !dst )
{
for ( i = 0; i < (unsigned int)len; ++i )
{
src = InOutBuff[i];
v = FnAlgorithm(seed, src);
t = v;
dst = FnAlgorithm(seed, v + src);
InOutBuff[i] = dst;
}
}
return dst;
}
假设要查询第20号单元,Cellx——由20和21号单元的字组成双字,Cell4——第4单元内容,Cell6——第6单元内容
能力值:
( LV3,RANK:30 )
3 楼
关注 . . .
能力值:
( LV2,RANK:10 )
4 楼
回退4年前看到这个代码,该激动得眼泪汪汪的了
现在SuperPro基本成为了历史。还是多谢南无阿弥陀佛
能力值:
( LV2,RANK:10 )
5 楼
sentinel superpro的关键是query/response,什么模拟器都是浮云。
求人不如求己,对于固定的具有大量的查询响应对的,以MultiKeyemu18.0.3为基础补丁实现。步骤如下:
1.编写查询响应对处理代码,RadAsm编译,编译出.obj,代码示例如下:
;#########################################################################
; Assembler directives
.486
.model flat,stdcall
option casemap:none
PUBLIC sproQuery
_page segment para public 'CODE' use32
assume cs:_page, es:nothing, ss:nothing, ds:_page, fs:nothing, gs:nothing
;org 00026080h
sproQuery proc iCell:BYTE,lpQueryData:DWORD,dogCellRaw:DWORD
push esi
push ebx
push ecx
push edx
mov edx, dogCellRaw ;dogCellRaw+156 -> cell_datas, dogCellRaw+156+128 -> cell_accesses.
mov bx, [edx+158]
.if bx != 01234h ; dongleID
pop edx
pop ecx
pop ebx
pop esi
ret
.endif
call getEndp
add eax, 2
mov esi, eax
movzx eax, iCell
.if ax == 36
add esi, 0
; mov esi, qr36
.elseif ax == 44
add esi,400h
; mov esi, qr44
.elseif ax == 52
add esi,800h
; mov esi, qr52
.endif
.if esi !=0
xor ecx, ecx
mov edx, lpQueryData
mov ebx, [edx]
.while ecx<128 && dword ptr [esi+ecx*8] != ebx
inc ecx
.endw
.if ecx<128
mov ebx, dword ptr [esi+ecx*8+4]
mov [edx], ebx
.endif
.endif
pop edx
pop ecx
pop ebx
pop esi
ret
sproQuery endp
getEndp proc
call get_cur_eip
get_cur_eip:
pop eax
ret
getEndp endp
qr36 dd 5042F79h, 0C4F4392Ah, 0F2EF4951h, 0B9F3FC1Bh, 43451C99h
。。。。。。
。。。。。。
2.用Winhex从.obj中剪切出关键代码,存到一个文件;
3.用CFF_Explorer导入上面文件,给MultiKey.sys扩用一个section,注意段的属性;
4.找到MultiKey.sys的查询响应代码部分手工补丁代码;
5.找工具给MultiKey.sys数字签名。
能力值:
( LV2,RANK:10 )
6 楼
学习了,继续关注中。。。。。。
能力值:
( LV2,RANK:10 )
7 楼
请问用什么工具可以查看和修改MultiKey.sys的代码?
能力值:
( LV2,RANK:10 )
8 楼
继续关注呀,最近看到这个头都是大的
能力值:
( LV2,RANK:10 )
9 楼
关注,一直在找个新版本可以用的模拟器,可惜自己还写不了