能力值:
(RANK:280 )
2 楼
我想是楼主对位的理解差异吧
例如0x01<<4之后应该是0x10
你把这个数值转为二进制数就好理解了
0x01=00000001
0x10=00010000
正好是4位
这个位移是用于定位数组中的指定单元的位置
能力值:
( LV2,RANK:10 )
3 楼
edx== 2的4次方吧
能力值:
( LV5,RANK:60 )
4 楼
是左移4位啊....没有错...
左移4位等于乘2^4(16).........
比如edx=2,shl edx,4后 edx=2*16=32(hex(32)=20)
也就是楼主看到的1位......
混淆了吧....十六进制和二进制了..........
能力值:
( LV9,RANK:190 )
5 楼
噢 ,哈哈,二楼正解。谢谢!
继续等待后面两个问题的答案。
能力值:
(RANK:280 )
6 楼
第二个问题 lea ecx, ecx这条指令不存在
8D /r LEA r32,m Store effective address for m in register r32
第二个字节是ModR/M,所以可以有lea ecx, [ecx]
第三个问题
FF15表示Call+绝对地址
FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
你要在其他地方修改代码只需要先输入FF 15并且把接下来的4个字节改成需要调用的函数的地址就好了
能力值:
( LV9,RANK:190 )
7 楼
楼上,不太明白。
第二个字节是ModR/M,所以可以有lea ecx, [ecx]
这意味着什么? 什么情况下会用到你说的这种情况?
我举个例子: ecx中是一个 数字,比如 0x03。
那 lea ecx, [ecx] 会发生什么? 第三个问题:
你描述的是怎样直接修改代码,必须知道函数的地址。那如果只知道函数名呢?在od的修改代码的功能中,能不能写入形如 call dword ptr [<&KERNEL32.GetProcessHeap>] 这样的代码,然后 od将其编译为 FF1500404544 这样的机器码?
能力值:
( LV11,RANK:188 )
8 楼
1.第一个问题注意是bits
2.lea eax,[eax];会经常看到的
[reg/mem]可错位的理解为*
lea reg,reg/mem/[reg/mem]可错位理解为&???
也可这样理解
[]运算符操作后返回值为一个地址
lea第二个操作符为一个指针
而其他的指令操作符绝多数为即时数
3.试试call dword ptr [kernel32.GetProcessHeap]
能力值:
( LV4,RANK:50 )
9 楼
[QUOTE=kusky;518361]
我举个例子: ecx中是一个 数字,比如 0x03。
那 lea ecx, [ecx] 会发生什么?
[/QUOTE]
会发生 eax = 0x03
lea Reg, [exp] ===> reg = exp
如,lea eax , [ eax * 4 + ecx * 3 + 1]
则, eax = eax * 4 + ecx * 3 + 1
呵呵,是不省了些事?
能力值:
(RANK:210 )
10 楼
lea reg32, [exp]
计算的时候不会影响到EFLAGS,另外简化了表达式计算
能力值:
( LV9,RANK:190 )
11 楼
原来大家都有早起的习惯~~~~
( 1 ) lea 怎样简化了操作呢?我看 mov也可以解决问题啊。
如,mov eax , [ eax * 4 + ecx * 3 + 1]
则, eax = eax * 4 + ecx * 3 + 1
不也是一样吗?
( 2 )
[ecx] 和 ecx 有什么不同?
按 intel的说法:
LEA - Load Effective Address
Transfers offset address of "src" to the destination register.
所以 lea eax , [ebp -100] 我能理解,这里 "[]"相当于c中的“&”
但 lea eax, [ecx] 为什么是取了ecx的内容呢?我理解应该是取ecx的地址,因为ecx没有地址,所以不能这样用。但试了却可以。
能力值:
( LV2,RANK:10 )
12 楼
如,mov eax , [ eax * 4 + ecx * 3 + 1]
则, eax = eax * 4 + ecx * 3 + 1
你在搞笑吗? 上面的相等吗? 所以 lea eax , [ebp -100] 我能理解,这里 "[]"相当于c中的“&”
但 lea eax, [ecx] 为什么是取了ecx的内容呢?我理解应该是取ecx的地址,因为ecx没有地址,所以不能这样用。但试了却可以。
上面的相当于 eax=ebp-100
另外一个就是 eax=ecx 了 强烈建议此帖发到新手区,太弱智的问题了
能力值:
( LV4,RANK:50 )
13 楼
[QUOTE=kusky;518414]原来大家都有早起的习惯~~~~
( 1 ) lea 怎样简化了操作呢?我看 mov也可以解决问题啊。
如,mov eax , [ eax * 4 + ecx * 3 + 1]
则, eax = eax * 4 + ecx * 3 + 1
不也是一样吗?
( 2 )
[ecx...[/QUOTE]
mov eax , [ eax * 4 + ecx * 3 + 1]
则, eax = eax * 4 + ecx * 3 + 1
这显然是错的
lea eax, ecx是非法的
能力值:
( LV2,RANK:150 )
14 楼
如果从纯数字意义上看shl edx,4 相当于edx=edx*16 。
但这里是对32 位int 类型的指针操作,也就是汇编语言中1个DWORD 类型的指针操作。
sizeof(int32 ) = sizeof(DWORD ) = 4*sizeof(BYTE )。
C语言的(32位的int 或long int ):
int *i;
i += 4;
对应于汇编语言的(假设edx 指向*i ):
shl edx, 4 ; edx=edx*16
因为汇编语言指令的基本单位是字节(BYTE )。
这样理解是否正确?
能力值:
( LV12,RANK:210 )
15 楼
简单来说
shl edx,4 就是edx=edx*16, 是值的语义
你那里不是 i+=4; 因为你的i是一个指针, +=4的是个下标, 应该是
i = i + 4 --->
不是
{
mov eax, i
shl eax, 4
mov i, eax
}
而是
{
mov eax, i
mov edx, 1
shl edx, 4
lea eax, [eax+edx]
mov i, eax
} int pi[3][4];
想要读pi[2][3];
可以
pi[2][3]
也可以
pi+2*4+3;
还可以
(int *) ( (char *)pi + 2*4*4 + 3*4 );
汇编地址都是char*的所以代码是下面这样
mov edx, 2;
shl edx, 4 // sizeof(int)*4 == 16, edx<<4 等价 edx = edx*16;
mov ecx, 3;
lea eax, [pi+edx+ecx*4]; eax = pi + 2*16 + 3*4;
mov eax, [eax]
能力值:
( LV2,RANK:150 )
16 楼
在Windows系统中大量的系统函数都是放在系统的动态连接库里,即以.dll为扩展名的文件中,如kernel32.dll、user32.dll、shell32.dll等等。
在汇编语言中要想用函数名的方式调用某个函数,一般要用LoadLibrary、GetProceAddress及FreeLibrary这三个Win32SDK函数。
以WinExec为例说明如下:
这4个函数都是kernel32.dll中的库函数,其调用信息分别为:
HINSTANCE LoadLibrary(
LPCTSTR lpLibFileName // 动态连接库文件名地址
);
FARPROC GetProcAddress(
HMODULE hModule, // 动态连接库句柄
LPCSTR lpProcName // 库函数名指针
); BOOL FreeLibrary(
HMODULE hLibModule // 一调入内存的动态连接库句柄
);
UINT WinExec(
LPCSTR lpCmdLine, // 应用程序命令行地址
UINT uCmdShow // 启动应用程序的窗口显示式样
);
汇编代码(不考虑任何异常情况):
DllLib db 'kernel32.dll',0
LoadLib db 'LoadLibrary',0
GetAddr db 'GetProcAddress',0
FreeLib db 'FreeLibrary',0
ExecCmd db 'WinExec',0
Notepad db 'Notepad.exe',0
mov eax, offset DllLib
push eax
call LoadLibraryA ; load kernel32.dll
mov ecx, eax ; save hModule
mov edx, offset ExecCmd
push edx ; lpProcName
push eax ; hModule
call GetProcAddress ; get address of WinExec
mov edx, 1 ; nCmdShow=1
push edx
mov edx, offset Notepad
push edx ; lpCmdLine
call eax ; call WinExec
mov eax, ecx ; get hModule
push eax
call FreeLibrary ; free kernel32.dll
能力值:
( LV9,RANK:190 )
17 楼
感谢诸位的热心回复。特别是 mstwugui ,jjnet,解决了我的问题。感谢 mavermaver 给我补充的知识~~
好像增加威望的功能不能用了?不知道如何感谢各位了~~~