• 我如何学习写代码

一直以来我都是从基础书本,从开源代码,从同事批评,从谷歌中改进自己”写代码”的技能.这里说的”写代码”,不是指具体的功能实现 函数调用,而是指一种编码习惯,例如命名习惯,留空习惯,注释习惯,等等在日常”写代码”中息息相关的片段.迄今为止我看过的没有那一本书(除了声名显赫的 code complete)教过我如何 跳出特定编程语言去写代码.这可能是我需要不断修炼的技能(去除特定的语法,语言,IDE,系统,最后程序员还剩下的东西 我估计那就是这里说的技能了.

  • 编译器如何写代码

今天我发现了一直伴随我身边的伙伴 – “编译器”,写代码技术已经是修炼到登峰造极的地步了,他给我的感觉 无异于 少林寺的扫地僧,首先看一段代码

// C/C++
int for1(int n)
{
    int i = 0;
    int s = 0;
    for(i = 0;i<n;i++)
    {
        s += i*2;
    }
    return s;
}

继续阅读

首先看一个简单的实现

在需要调用的地方写入一下代码:

try
{
	sJump = Class.forName("com.rect.jumpdemo.JumpHandle");
	if(sJump != null)
	{
		Method method = 
     sJump.getMethod("CallBack", new Class[] { Integer.TYPE});
		if(method != null)
	   method.invoke(null, new Object[] { Integer.valueOf(11)});
	}
}
catch (Exception e) {
	// TODO: handle exception
}

继续阅读

把逆向丢了有一段时间了,总觉得有些东西应该坚持研究下去。最近一年在做移动项目的时候一直都想把整个android底层了解清楚。

直到最近有点时间空余下来。一段时间后发现android的芯片ARM的ARM汇编和x86的16,32位汇编其实原理是相通的,只是可能在语法 在硬件结构上会导致有差别。(虽然这篇文章并用不到这种东西),而相比于android的Dalvik虚拟机代码,Dalvik机器码更便于阅读。只要好好记住Dalvik的一些规则便可。

然后我们从简单的逆向开始吧。这篇我会拿一个有广告的android应用来试手,当然原理本身非常简单,当然并没有针对的意思,下面是一个简单的使用逆向技术而修改程序的过程:

使用到的工具:IDA,C32ASM,JD-gui,Notepat++,apktool,android签名工具。

需要做手术的应用:某事百科。

继续阅读

毕业两个月了,工作了三个月后。。

最终一切又回归到了原点。

选择了一个节奏快的城市

每天都活在奔跑中。。

很多时候其实挺喜欢这种感觉

好久没去反汇编了。。看到OD代码页的感觉真棒。

果然还是汇编比较有亲和力。。。

一组Key:

ShadowKong

5BDDCC8C

CM

最近温故了下16位的汇编.

用惯了MASMPLUS之后再去试试以前用过的编写器轻松汇编

发现其实轻松汇编也不错.

主要是发现2.7版本的提供了映像文件和交叉文件~

交叉文件刚好是汇编指令和机器码的对照~

这功能不错 省的载入OD了就可以直接看机器码了~

不过对于那个开始那个关联文件的对话框有点不爽~

于是顺手把它去了..

去这个对话框其实也很简单,为了熟悉机器码我们采用之间修改机器码的方式..

载入UE 来到文件偏移00077AA6处:

然后修改(括号里面的是原数据)

77AA6: 33 (56)
77AA7: C0 (8B)
77AA8: EB (45)
77AA9: 08 (F8)
33 对应    [cc lang=”asm”]xor eax,eax[/cc]
EB  08  是[cc lang=”asm”] JMP  $+8[/cc]
等于是选择了[否]

这是一个非常有意思的CrackMe!

首先查壳 又是UPX 直接手脱 脱壳毫无技术含量不值一提.

然后载入OD直接找到算法部分~

发现这个CM比较特别 其中的两个静态变量作为标志更是亮点中的亮点~

这意味着要输入两次Key验证,第一次使得第一个STATIC a==1,b==1;

第二次使得STAIC b++;

要当a==1,b==2的时候才算CONS~

在验证过程会发现算法只取前8位注册码 不够8位用0x20补全~

而且这个算法也是这个CM的非常漂亮的地方之一,特别是第一轮的~:

第一轮:

/*************************************************/

004568FC  /$  55            push    ebp
004568FD  |.  31C9          xor     ecx, ecx
004568FF  |.  8D30          lea     esi, dword ptr [eax]
00456901  |.  83C6 04       add     esi, 4
00456904  |.  BB 998F3337   mov     ebx, 37338F99
00456909  |.  AD            lods    dword ptr [esi]                  ;  后四位
0045690A  |.  31C3          xor     ebx, eax
0045690C  |.  C1C3 30       rol     ebx, 30
0045690F  |.  81F3 00009999 xor     ebx, 99990000
00456915  |.  C1CB 50       ror     ebx, 50
00456918  |.  83EE 08       sub     esi, 8
0045691B  |.  AD            lods    dword ptr [esi]                  ;  前四位
0045691C  |.  01C3          add     ebx, eax
0045691E  |.  81F3 99999999 xor     ebx, 99999999
00456924  |.  C1C3 70       rol     ebx, 70
00456927  |.  81FB 75533D53 cmp     ebx, 533D5375
0045692D      75 1C         jnz     short 0045694B
0045692F  |.  41            inc     ecx/*标志*/
00456930  |.  83EE 04       sub     esi, 4
00456933  |.  AD            lods    dword ptr [esi]                  ;  前四位
00456934  |.  89C3          mov     ebx, eax
00456936  |.  AD            lods    dword ptr [esi]                  ;  后四位
00456937  |.  C1CB 80       ror     ebx, 80
0045693A  |.  81F3 99990000 xor     ebx, 9999
00456940  |.  31C3          xor     ebx, eax
00456942  |.  81FB 998F3337 cmp     ebx, 37338F99
00456948      75 01         jnz     short 0045694B
0045694A  |.  41            inc     ecx/*标志*/
0045694B  |>  5D            pop     ebp
0045694C  \.  C3            retn
/******************************************************/
分析算法之前我们设两个变量:
L4==后四位注册码
F4==前四位注册码
把上面第一轮的算法翻译成数学公式就是:
(I)
(((((L4 xor 0x37338F99)rol 0x10)xor 0x99990000)rol 0x10+F4)xor 0x99999999)rol 0x10 ==0x533D5375
(II)
(F4 xor 0x00009999) xor L4==0x37338F99
由上面的(I)(II)可得:
(III)
L4==0x37338F99 xor (F4 xor 0x00009999)
再由(I)(III)可得:
(IIII)
(((((F4 xor 0x00009999)rol 0x10)xor 0x99990000)rol 0x10+F4) xor 0x99999999)rol 0x10==0x533D5375
由(IIII)可以看出 F4在第一轮中高低位互相不影响~也就是说 在这里L4 高低位是独立的~
然后我们由(IIII)推出L4  F4的计算公式:
F4=((0x533D5375 rol 0x10)xor 0x99999999)/2
L4=(F4 xor 0x9999)xor 0x37338F99
然后 第一个注册码就是:F4+L4 ==ReveRsER
第二轮的算法相对于第一轮来说没啥好说的~
/******************************************************/

一组Key:

FirstTime:ReveRsER

SecondTime:CraCkiNG

DownMe:KeyGen

这个CM和以往的有点区别~亮点还是有的~

首先PEID查看 有壳~~

我们重点不是这 轻易脱掉

首先这并不是明码比较(很多都不是明码比较..)

其次这是一组Name 和Key混合算法

再其次这个算法的关键在于:

A[i]=F1(Name[i-1])-F2(Key[i-1]);

i=KeyLen+1;

然后循环算出A[KeyLen];

最后再比较~~

总之这个算法不需要逆 但是需要有很好的数学思维 特别是数列和解N个变量的方程函数方面的…

最后这个CM有几处代码非常漂亮:

004013C3    BF 20334000     mov     edi, 00403320
004013C8    BE 20334000     mov     esi, 00403320
004013CD    AC              lods    byte ptr [esi]
004013CE    0C 00           or      al, 0
004013D0    74 05           je      short 004013D7
004013D2    0C 20           or      al, 20
004013D4    AA              stos    byte ptr es:[edi]
004013D5  ^ EB F6           jmp     short 004013CD

如果你有点汇编基础 就看看出这段代码是多么的漂亮~

一组可用Key:

ShadowKong

rg`\e

DownMe:KeyGen

注册机并不完美 因为这算法解太多…