假設(shè)輸入的用戶名和序列號(hào)為:
11111
22222
004010D6? |.? B9 10000000?? mov???? ecx, 10
004010DB? |.? 2BC8????????? sub???? ecx, eax
004010DD? |.? BE 60214000?? mov???? esi, 00402160??????????????????????????? ;? ASCII "11111"
004010E2? |.? 8BFE????????? mov???? edi, esi
004010E4? |.? 03F8????????? add???? edi, eax
004010E6? |.? FC??????????? cld
004010E7? |.? F3:A4???????? rep???? movs byte ptr es:[edi], byte ptr [esi]
004010E9? |.? 33C9????????? xor???? ecx, ecx
004010EB? |.? BE 71214000?? mov???? esi, 00402171??????????????????????????? ;? ASCII "22222"
ecx = 0x10
ecx = ecx - eax = 0x10 - 0x5 = 0x0b
esi =??00402160?
edi = 00402160?
edi= edi+0x5 = 00402165
使標(biāo)志位 D 為0
接下來(lái)是這一個(gè)語(yǔ)句:? 004010E7? |.? F3:A4???????? rep???? movs byte ptr es:[edi], byte ptr [esi]
此時(shí) edi 指向 用戶名后面的數(shù)據(jù)空間
edi = 0x00402165
00402155? 40 79 61 68 6F 6F 2E 63 6F 6D 00 31 31 31 31 31? @yahoo.com.11111
00402165? 00 00 00 00 00 00 00 00 00 00 00 00 32 32 32 32? ............2222
00402175? 32 00 00 00 00 00 00 00 00 00 00 00 00 98 BA DC? 2............樅
esi = 0x00402160
esi 指向輸入的用戶名
rep 指令
格式:REP MOVS(或REP STOS,或REP LODS)
執(zhí)行的操作:使REP后面的串操作指令重復(fù)執(zhí)行,執(zhí)行的次數(shù)預(yù)先存放在CX寄存器中,每執(zhí)行一次串操作指令,CX寄存器的內(nèi)容自動(dòng)減1,一直重復(fù)執(zhí)行到CX=0,指令才結(jié)束。具體的操作步驟是:
第1步 如果CX=0,則退出REP,否則執(zhí)行REP后面的串操作指令;
第2步 CX ← CX-1;?
第3步 執(zhí)行串操作指令
第4步 重復(fù)第1步~第3步。
rep???? movs byte ptr es:[edi], byte ptr [esi]
的意思是,重復(fù)執(zhí)行? movs byte ptr es:[edi], byte ptr [esi] 這個(gè)語(yǔ)句,次數(shù)是 ecx 寄存器中的次數(shù)
1. esi 指向輸入的用戶名
2. edi 指向輸入用戶名后面的內(nèi)存
3. ecx 是通過(guò) 0x10- 輸入用戶名的長(zhǎng)度得來(lái)的
也就是說(shuō),如果輸入的用戶名,不足 0x10 這個(gè)長(zhǎng)度, 就是用‘輸入的用戶名’重復(fù)去填充,直至 0x10 這個(gè)長(zhǎng)度
如果輸入的用戶名已經(jīng)是 0x10 這個(gè)長(zhǎng)度,那么就不做任何操作了
執(zhí)行完之后的結(jié)果
00402155? 40 79 61 68 6F 6F 2E 63 6F 6D 00 31 31 31 31 31? @yahoo.com.11111
00402165? 31 31 31 31 31 31 31 31 31 31 31 00 32 32 32 32? 11111111111.2222
00402175? 32 00 00 00 00 00 00 00 00 00 00 00 00 98 BA DC? 2............樅
接下來(lái)的代碼:
004010E9? |.? 33C9????????? xor???? ecx, ecx
004010EB? |.? BE 71214000?? mov???? esi, 00402171??????????????????????????? ;? ASCII "22222"
004010F0? |>? 41??????????? /inc???? ecx
004010F1? |.? AC??????????? |lods??? byte ptr [esi]
004010F2? |.? 0AC0????????? |or????? al, al
004010F4? |.? 74 0A???????? |je????? short 00401100
004010F6? |.? 3C 7E???????? |cmp???? al, 7E
004010F8? |.? 7F 06???????? |jg????? short 00401100
004010FA? |.? 3C 30???????? |cmp???? al, 30
004010FC? |.? 72 02???????? |jb????? short 00401100
004010FE? |.^ EB F0???????? \jmp???? short 004010F0
00401100? |>? 83F9 11?????? cmp???? ecx, 11
00401103? |.? 75 1A???????? jnz???? short 0040111F
00401105? |.? E8 E7000000?? call??? 004011F1
INC OPR //Byte/Word
執(zhí)行操作: OPR=OPR+1
1.OPR可以是寄存器和存儲(chǔ)器操作數(shù), 但不能是立即數(shù)和段寄存器
2.影響標(biāo)志位OF,SF,ZF,PF 和AF,不影響CF
lods
字符串操作中,從串取指令,從DS:SI所指向的空間中取出一個(gè)字節(jié)/字/雙字放入寄存器中AL/AX/EAX,同時(shí)把SI+(-)1/2/4.(LODS相當(dāng)于MOV AL,[SI]?? INC SI.)
從串取指令就是從DS:SI所指向字符串中取出一個(gè)字符.
ecx = 0
esi = 00402171? (esi 指向輸入的序列號(hào))
ecx += 1
eax=0x32?????? esi+=1?? == 0x00402171 + 1 = 0x00402172 (取出序列號(hào)的一個(gè)字母,并把 esi 指向下一個(gè)字母)
or????? al, al?? (判斷上一步取出來(lái)的字符是否為 0,?? 因?yàn)?lods 指令用了 byte ptr, 所以這里只需要比較 al 就可以了)
|je????? short 00401100??? (如果al,即取出來(lái)的字符等于0,就是跳轉(zhuǎn)到00401100???,字符取出來(lái)有可能是0????? 這里的 0 是結(jié)束字符?)
cmp???? al, 7E??? (將 al 跟 0x7e 進(jìn)行比較, 7e 的十進(jìn)制是 126,? 7E 對(duì)應(yīng)的字符是 '~')
jg????? short 00401100?? ( j 表示 jump,? g 表示 greater , 也就是說(shuō),取出來(lái)的字符如果大于 '~' 這個(gè)字符,就是跳轉(zhuǎn)到 00401100 )
cmp???? al, 30???? (將 al跟 0x30 進(jìn)行比較,30的十進(jìn)制是 48, 0x30 對(duì)應(yīng)的字符是 '-')
jb????? short 00401100? ( j 表示 jump, b 表示 below, jb 判斷 cf 標(biāo)志位,低于時(shí)跳轉(zhuǎn), jl 用于帶符號(hào)的運(yùn)算,jb用于 無(wú)符號(hào)的運(yùn)算)
看回 ascii 表示,可見(jiàn)字符是從 0x30 - 0x7E,? 上面這幾句很明顯,是在判斷輸入序列號(hào)的字符是否合法
同時(shí) ecx 存放著序列號(hào)的長(zhǎng)度
0401100? |>? 83F9 11?????? cmp???? ecx, 11?????? ;? ecx 跟 11 比較
00401103? |.? 75 1A???????? jnz???? short 0040111F
cmp 算術(shù)減法運(yùn)算結(jié)果為零,就把ZF(零標(biāo)志)置1.??? jnz 判斷當(dāng) ZF(零標(biāo)志位)為 0 時(shí)就跳轉(zhuǎn)
所以這兩個(gè)語(yǔ)句就是,當(dāng) ecx 不等于 0x11, 就?跳轉(zhuǎn)到 0040111F
0040111F? |> \C3??????????? retn
0040111F? 是一個(gè) retn?,,,,,,
按 F9 讓它過(guò)去,然后把序列號(hào)改為? 2222222222222222????? (16個(gè)2)
當(dāng) ecx == 11 時(shí),會(huì)繼續(xù)往下走, call 004011F1
00401100? |> \83F9 11?????? cmp???? ecx, 11
00401103? |.? 75 1A???????? jnz???? short 0040111F
00401105? |.? E8 E7000000?? call??? 004011F1
0040110A? |.? B9 01FF0000?? mov???? ecx, 0FF01
0040110F? |.? 51??????????? push??? ecx
00401110? |.? E8 7B000000?? call??? 00401190
F7 跟進(jìn)子調(diào)用 004011F1
代碼如下:
004011F1? /$? A1 60214000?? mov???? eax, dword ptr [402160]
004011F6? |.? 8B1D 64214000 mov???? ebx, dword ptr [402164]
004011FC? |.? 3305 71214000 xor???? eax, dword ptr [402171]
00401202? |.? 331D 75214000 xor???? ebx, dword ptr [402175]
00401208? |.? 25 0F1F3F7F?? and???? eax, 7F3F1F0F
0040120D? |.? 81E3 00010307 and???? ebx, 7030100
00401213? |.? 33C9????????? xor???? ecx, ecx
地址 402160 指向的是輸入的用戶名開(kāi)頭
地址 402164 指向的是輸入的用戶名第五個(gè)字節(jié)
地址 402171 指向的是輸入的序列號(hào)開(kāi)頭
地址 402175 指向的是輸入的序列號(hào)第五個(gè)字節(jié)
那么語(yǔ)句的意思大概是
1. 用戶名的前1-4個(gè)字節(jié)放到? eax
2. 用戶名的前5-8個(gè)字節(jié)放到 ebx
3. 用戶名與序列號(hào)的前四個(gè)字節(jié)異或放到 eax
4. 用戶名與序列號(hào)的前5-8字節(jié)異或放到 ebx
5. eax 位與 0x7F3F1F0F? 放到 eax
6. ebx 位與 0x7030100??? 放到 ebx
7. ecx 清 0
接著往下看
00401213? |.? 33C9????????? xor???? ecx, ecx
00401215? |>? 8BF0????????? /mov???? esi, eax
00401217? |.? 8BFB????????? |mov???? edi, ebx
00401219? |.? D3E6????????? |shl???? esi, cl
0040121B? |.? D3E7????????? |shl???? edi, cl
0040121D? |.? 81E6 80808080 |and???? esi, 80808080
00401223? |.? 81E7 80808080 |and???? edi, 80808080
00401229? |.? 8BD6????????? |mov???? edx, esi
1. 把 eax 放到 esi
2. 把 ebx 放到 edi
把 eax 和 ebx 分別放到 esi, edi 干嘛?
shl 指令是邏輯左移,右面補(bǔ)零。
shl? x, y????? y為移動(dòng)的位數(shù)
00401219? |.? D3E6????????? |shl???? esi, cl
0040121B? |.? D3E7????????? |shl???? edi, cl
此時(shí), cl 為0, 所以這兩句暫時(shí)沒(méi)用
0040121D? |.? 81E6 80808080 |and???? esi, 80808080
00401223? |.? 81E7 80808080 |and???? edi, 80808080
接著把 esi 跟 edi 分別跟 0x80808080 與
00401229? |.? 8BD6????????? |mov???? edx, esi??? ;?? 把 esi 放到 edx
0040122B? |.? C0EE 07?????? |shr???? dh, 7????? 對(duì)dh右移7位
0040122E? |.? 66:C1E2 07??? |shl???? dx, 7???? 對(duì)dx左移7位
把 dx 的后半截清0, 不過(guò)此時(shí)dx為0, 所以這兩句暫時(shí)不起
00401232? |.? C1EA 08?????? |shr???? edx, 8
00401235? |.? C0EE 07?????? |shr???? dh, 7
00401238? |.? 66:C1E2 07??? |shl???? dx, 7
0040123C? |.? C1EA 08?????? |shr???? edx, 8
0040123F? |.? C0EE 07?????? |shr???? dh, 7
00401242? |.? 66:D1EA?????? |shr???? dx, 1
上面的一堆指令都是對(duì) edx 進(jìn)行無(wú)聊的移位
00401245? |.? 8BF2????????? |mov???? esi, edx
00401247? |.? 8BD7????????? |mov???? edx, edi
將?edx 放到 esi
將 edi 放到 edx?
接著往下看
00401270? |.? 51??????????? |push??? ecx????????????????????????????????? 將 ecx 跟 edx 都放到堆棧, 此時(shí) ecx 跟 edx 都為 0, 沒(méi)意義
00401271? |.? 52??????????? |push??? edx
00401272? |.? BA 08000000?? |mov???? edx, 8???????????????????? edx = 8
00401277? |.? 91??????????? |xchg??? eax, ecx??????????????????????????? 交換指令XCHG(exchange),??? ecx 跟 eax 交換,? eax 在上邊是取用戶名前四位進(jìn)行一些位操作的結(jié)果
00401278? |.? 83F8 03?????? |cmp???? eax, 3???????????????????????????比較 eax 跟 3
0040127B? |.? 7F 0F???????? |jg????? short 0040128C????????????????如果 eax 大于 3 則跳轉(zhuǎn)
0040127D? |.? F6E2????????? |mul???? dl???????????????????????????????????? 此時(shí) dl 為0
0040127F? |.? 5A??????????? |pop???? edx??????????????????????????????????? 恢復(fù) edx
00401280? |.? 83C0 08?????? |add???? eax, 8???????????????????????????? eax + 8
00401283? |.? 91??????????? |xchg??? eax, ecx?????????????????????????????? eax 跟 ecx 交換
00401284? |.? D3C0????????? |rol???? eax, cl??????????????????????????????? ROL 循環(huán)左移指令 , 左移,移出位填充到右邊最高位
00401286? |.? 33C2????????? |xor???? eax, edx??????????????????????????? 此時(shí),edx 為 0, 所以 eax 的值還是不變
00401288? |.? D3C8????????? |ror???? eax, cl?????????????????????????????? ROR 循環(huán)右移指令,? 右移,移出位填充到左邊最高位
0040128A? |.? EB 0D???????? |jmp???? short 00401299
0040128C? |>? 83E8 03?????? |sub???? eax, 3
0040128F? |.? F6E2????????? |mul???? dl
00401291? |.? 5A??????????? |pop???? edx
循環(huán)移位指令
格式: ROL OPRD1,COUNT ;不含進(jìn)位標(biāo)志位CF在循環(huán)中的左循環(huán)移位指令.
? ?? ?ROR OPRD1,COUNT ;不含進(jìn)位示志位CF在循環(huán)中的右循環(huán)移位指令.
? ?? ?RCL OPRD1,COUNT ;帶進(jìn)位的左循環(huán)移位指令.
? ???RCR OPRD1,COUNT ;帶進(jìn)位的右循環(huán)移位指令.
說(shuō)明:
1. 本指令組只影響標(biāo)志CF、OF.OF由移入CF的內(nèi)容決定,OF取決于移位一次后符號(hào)位是否改變,如改變,則OF=1.
2. 由于是循環(huán)移位,所以對(duì)字節(jié)移位8次; 對(duì)字移位16次,就可恢復(fù)為原操作數(shù).由于帶CF的循環(huán)移位,可以將CF的內(nèi)容移入,
? ?所以可以利用它實(shí)現(xiàn)多字節(jié)的循環(huán).
?