|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
对于这次衔接上导致的问题只能说非常抱歉了。是否扣分的事得商议后决定了,当然希望对大家都尽量公平一些。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
很抱歉,才发现这个问题。正好这几天有点事情,和他们在衔接过程中考虑不周,导致附件中的图示顺序和论坛上的图示顺序不完全一致,还是以论坛上公布的图示顺序为准吧。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
其实我个人对用什么语言倒不排斥。反而更希望各位能用自己熟悉的语言.而且相比C/delphi等后来出现的语言本身提供的语法特性可能在开发效率上更好一些。 不过定什么标准用什么写也不是我一个人能说了算的。。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
没问题。不过也别用ASM写完,再弄个内联的套子就行。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
这题其实就是把我以前玩过的一个拼盘游戏转成了算法题。希望不会那么凑巧。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
举例来说,第一个红色的滑块用字符表示就是如下: 000000 00000000 00000000 000000 第二个绿色的滑块用字符表示就是如下: 1111111 11111 11111 1111111 解释一下,每个滑块都是由6个小三角组成。当用字符表示时,每个小上三角用 ? ??? 来表示。 每个小下三角用 ??? ? 来表示。 其中 ? 号用每个滑块对应的字符来代替。比如第一个红色滑块对应字符为0,那么组成它的字符都用0。同理第二个绿色滑块组成它的字符都用1,以此类推。 在附件最后有一个示例。不过滑块对应的字符与竞赛要求的对应关系有些不同。正确的应该如下: 00000 0000000 10000000A 11100000AAA 11111111AAAAA 11111111AAAAAAA BBBB3111AAAA22222 BBBB3331AAAA2222222 BBBB33334444222252227 BBBB3333444422225552777 BBBB933334444555555577777 BBBB99933334444555557777777 999999963334444555587778777 9999966634444555588878887 99996666666666688888888 999966666666688888888 (晕,示例第一行排版有点问题,希望不影响理解) |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
附件最后有一个示例。用12个滑块组成一个拼盘图示要16行。你数一数就明白了。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
输出结果是用12个滑块拼成的拼盘的组成图示,用字符形式表示。在附件的文档中最后有一个图例。要求用字符形式表示,也考虑到评分方便一些。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
[QUOTE=forgot;521594]为什么限制 C / C++, DELPHI?鄙视用ASM的吗?[/QUOTE] 不敢鄙视,怕ASM写个上万行的,看不懂。 另外语言可用种类不多,也考虑到不同语言在执行速度上,如果差异过多会对评分标准也有影响。 |
|
[结束][第二阶段◇第一题]看雪论坛.腾讯公司2008软件安全技术竞赛
你这种的表示形式我试过,有些滑块不同的角度变化时图形表示区别不明显。所以为了统一,请还是用题目公布的那样吧。 |
|
[求助]几个《加密与解密3》的问题
在IDA的SDK中吧。用 IDA SDK 搜索一下论坛就可以捞到。http://bbs.pediy.com/showthread.php?t=55801 |
|
[讨论]《加密与解密 第3版》SMC的一个令人费解的bug!!
很抱歉现在才进行回复,主要是一检查才发现问题还不少,很惭愧,所以多花了些时间修正。 先说一下需要修正的地方: 1) 书中: mov [sContext].iDr7, 11h 此行代码应改为 mov [sContext].ContextFlags, CONTEXT_DEBUG_REGISTERS mov [sContext].iDr7, 101h 原来的代码中设置 DR7 的值为 11h 计算错误,应为 LOCAL_EXACT_BPM_ENABLED 与 DR0_ENABLED 的或值,即 101h 。 同时应该添加对标志寄存器 ContextFlags 的操作,否则无法设置调试寄存器。 2) 随书光盘 OSMC.ASM 的代码 DecryptFunc 函数 DecryptFunc proc uses ebx ecx edx esi edi lpBuffer:LPVOID,nBuffSize:DWORD mov esi,lpBuffer mov edi,esi mov ecx,nBuffSize shl ecx,2 <-- 此处应添加这行代码 loc_loop: lodsb dec al stosb loop loc_loop ret DecryptFunc endp 同时随书光盘 TrSMC.ASM 的代码 EncryptFunc 函数 EncryptFunc proc uses ebx ecx edx esi edi lpBuffer:LPVOID,nBuffSize:DWORD mov esi,lpBuffer mov edi,esi mov ecx,nBuffSize shl ecx,2 <-- 此处应添加这行代码 loc_loop: lodsb inc al stosb loop loc_loop ret EncryptFunc endp 这里原来的代码中在调用加密解密函数时使用的是DWORD长度,但实际上加密解密函数是按字节进行操作的。所以这里必须加上以上两行代码。 3) 随书光盘 TrSMC.ASM 的代码 CreateImage 函数 ;-=-=定位到PE文件头=-=- push FILE_BEGIN push 0 <-- 此处应添加这行代码 push [dwPeOffset] push [hFile] call SetFilePointer 这里原来的代码中调用 SetFilePointer API时少了一个参数,使得运行 TrSMC.EXE 时无法正确生成 SMC.EXE 程序。 最后再来解释一下 SMC.EXE 中的所使用的两种反跟踪代码的作用。 即第一段 pushf or byte ptr [esp+1],01h popf nop 第二段 pushad mov edi,offset sContext mov ecx,sizeof CONTEXT xor eax,eax cld rep stosb invoke GetCurrentThread mov edi,eax mov [sContext].ContextFlags, CONTEXT_ALL invoke GetThreadContext,edi,addr sContext mov [sContext].ContextFlags, CONTEXT_DEBUG_REGISTERS mov [sContext].iDr7,101h ;LOCAL_EXACT_BPM_ENABLED + DR0_ENABLED invoke SetThreadContext,edi,addr sContext popad 本意上写 SMC 这一节时希望能够把原理讲清楚,代码设计不是太复杂,对初学者而言能够更容易看懂。所以反跟踪的代码并没有在书中详细介绍其作用。 完整的代码也只放在随书光盘中。 在实际运用中通常仅仅只靠SMC来做安全保护,往往显得比较单薄,对于熟练的调试者来说很容易跳过。他的缺陷在哪儿呢? 这里介绍的SMC用作安全保护的原理是利用SMC来依次分段解密后面要运行的代码,边运行边解密。解密代码的密钥则是通过计算之前运行的代码字节与长度而得。即 KEY = CalcKEY(INIT_KEY, PrevCode, PrevCodeLen) NextCode = Decrypt(NextCode, KEY) 如果之前运行的代码字节被修改,则计算的密钥错误从而无法正确解密出后面要运行的代码。 这种设计可以防范利用 INT 3 断点进行跟踪的方式,也就是说当调试者试图在当前运行的代码的某处下 INT 3 断点时,会导致代码字节被修改。这样就影响了 程序解密其后的代码的密钥,而密钥错误时解密代码得到的是一堆乱七八糟的字节,自然无法继续对其后代码的跟踪。 但是我们知道除了利用 INT 3 断点进行跟踪之外,还可以使用单步跟踪和硬件调试器断点进行跟踪。而以上的设计并不能防范这两种方式的调试跟踪。 于是针对这种设计的缺陷,需要在代码中加入相关的反跟踪代码与SMC结合,这样才能更好的防范调试者。书中主要考虑以介绍SMC的基本运用为主,就没有为此详细展开说明,这里就来多说几句。 前面加入的第一段反跟踪代码,针对的主要是单步跟踪。当程序没有被调试者跟踪时,执行到 popf 代码时会产生单步异常。而程序中之前已经通过以下代码 Block1: call loc_next .... loc_next: push fs:[0] mov fs:[0],esp 建立了自己的异常处理函数。异常处理函数首地址即为 call loc_next 的下一条指令。 ;-=-=这里是异常处理函数的起始地址=-=- mov esi,[esp+4] assume esi:ptr EXCEPTION_RECORD mov edi,[esp+0Ch] assume edi:ptr CONTEXT cmp [esi].ExceptionCode,EXCEPTION_SINGLE_STEP jz @F mov eax,ExceptionContinueSearch ret @@: mov eax,[edi].regEax xchg eax,[edi].regEdx mov [edi].regEax,eax xor eax,eax mov [edi].iDr0,eax and [edi].iDr1,eax and [edi].iDr2,eax and [edi].iDr3,eax and [edi].iDr6,0FFFF0FF0h and [edi].iDr7,eax mov [edi].ContextFlags,CONTEXT_ALL mov eax,ExceptionContinueExecution ret 当程序产生单步异常时,异常处理函数中的处理主要是交换 EAX 和 EDX 寄存器的值,然后程序返回到异常点继续执行。 这里交换寄存器的作用是什么呢?我们来看程序中计算密钥的一段代码: @@: lodsd xor eax,edx xor eax,ecx ;-=-=把反跟踪与计算相结合=-=- pushf or byte ptr [esp+1],01h popf nop loop @B 以上代码中,EDX 初始值为 INIT_KEY ,ECX 为代码长度,EAX 为加密的代码字节。可以看到如果没有异常处理函数交换 EAX 和 EDX 寄存器,那么每一轮循环 时计算得到的值都保存在 EAX 中,在下一轮循环时由于 lodsd 指令,会丢失之前计算的 EAX 的值。而利用 pushf / popf 产生异常,在异常处理函数中交换 寄存器值,即功能等同于以下的代码: @@: lodsd xor eax,edx xor eax,ecx xchg eax,edx loop @B 这样最后在 EDX 中保存的即是计算得到的密钥值。 如果试图单步跟踪这段代码,误入陷阱的话,在这里就是单步跟踪到 popf 时,则不会再产生单步调试异常,直接运行到其后的 nop 指令处,由于没有运行异常处理函数 因而 EAX 和 EDX 寄存器值也就没有交换,最后计算的密钥也就是错误的。 如果你知道了这个原理,作为调试者时当然不会再傻到单步跟踪 pushf / popf 的地步。但同样如果明白了原理,也可以结合其他的反单步跟踪的代码与SMC方法结合来反跟踪。 现在再来介绍第二段反跟踪代码。其实这段代码也是后来才加入到整个程序之中,所以在代码开始和结束时用了 pushad / popad 对所有寄存器进行保存和恢复。你也可以注释掉 这段代码后重新编译下,来调试跟踪对比一下。 这段代码也是加在计算密钥的流程之中,如果误入陷阱,同样会影响到密钥的计算,最后导致无法跟踪到下一段利用SMC解密得到的代码。 这段代码通过使能DR0调试寄存器,使得调试者不能在跟踪时随意使用硬件寄存器断点或BPM断点,一旦设下断点,在使用 OllyDBG 调试时运行到 SetThreadContext 时可能会触发断点,从而改变了程序的流程,最终将影响程序的继续运行。 |
|
VMProtect[报毒计划]
考验各种kv的杀毒引擎的时候到了。。 |
|
[讨论]有关支持大家出书的想法
支持一下。。 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值