【X86】変数を確保していない関数内で代入引数のある関数を呼ぶ
変数を確保していなかったり、スタックフレームが生成されていない関数内で
代入引数のある関数を呼び出すためのテクニックの紹介です
int WINAPI Val1Func(DWORD *val)
と言う関数があったとします。
push 0 // 初期値 push esp call Val1Func pop eax |
これで関数呼び出し後、最初の pop で代入された valが取り出せます。
(ebpを使わずに)スタックフレームがないなら作る訳です。
2バイト以上の変数引き渡しが必要な場合は少し複雑になります
int WINAPI Val2Func(DWORD *val, DWORD *val2)
mov eax, 0xbadbeef push eax // 初期値1 push eax // 初期値2 mov eax,esp push eax // 引数2のポインタ |
初期化が不要な場合は sub esp,4*変数の数 でも構いません
これが基本計で、 最初の push eax と add eax,4 / push eax と pop が増えるだけです
as the number of arguments increases. The key is to pass the pointers to the arguments in reverse order, as the arguments are pushed onto the stack in reverse order.
Overall, this technique can be useful in situations where a variable or stack frame cannot be allocated, but arguments still need to be passed to a function with assignments. It requires careful management of the stack and pointer manipulation, but can save valuable memory resources in certain cases.
example given:
int WINAPI Val1Func(DWORD *val) {
// function implementation
}
int WINAPI Val2Func(DWORD *val, DWORD *val2) {
// function implementation
}
void exampleFunction() {
// calling Val1Func with one argument
push 0 // initial value
push esp
call Val1Func
pop eax // retrieve val assigned by Val1Func
// calling Val2Func with two arguments
mov eax, 0xbadbeef
push eax // initial value 1
push eax // initial value 2
mov eax, esp
add eax, 4 // move pointer to second argument
push eax // pointer to argument 2
mov eax, esp
sub eax, 8 // move pointer to first argument
push eax // pointer to argument 1
call Val2Func
// retrieve values assigned by Val2Func
pop edx // val2
pop eax // val1
// adjust stack if necessary
sub esp, 8 // for two arguments, no initialization needed
}
Note that depending on the compiler and calling convention, the order in which arguments are pushed onto the stack may differ, and the use of registers such as eax, ebx, ecx, etc. may be necessary to ensure correct argument passing and value retrieval.
as the number of arguments increases. The key is to pass the pointers to the arguments in reverse order, as the arguments are pushed onto the stack in reverse order.
Overall, this technique can be useful in situations where a variable or stack frame cannot be allocated, but arguments still need to be passed to a function with assignments. It requires careful management of the stack and pointer manipulation, but can save valuable memory resources in certain cases.
example given:
int WINAPI Val1Func(DWORD *val) {
// function implementation
}
int WINAPI Val2Func(DWORD *val, DWORD *val2) {
// function implementation
}
void exampleFunction() {
// calling Val1Func with one argument
push 0 // initial value
push esp
call Val1Func
pop eax // retrieve val assigned by Val1Func
// calling Val2Func with two arguments
mov eax, 0xbadbeef
push eax // initial value 1
push eax // initial value 2
mov eax, esp
add eax, 4 // move pointer to second argument
push eax // pointer to argument 2
mov eax, esp
sub eax, 8 // move pointer to first argument
push eax // pointer to argument 1
call Val2Func
// retrieve values assigned by Val2Func
pop edx // val2
pop eax // val1
// adjust stack if necessary
sub esp, 8 // for two arguments, no initialization needed
}
Note that depending on the compiler and calling convention, the order in which arguments are pushed onto the stack may differ, and the use of registers such as eax, ebx, ecx, etc. may be necessary to ensure correct argument passing and value retrieval.