BGDK111 发表于 2024-11-14 18:24

如何找到入口点

怎么寻找入口点Main函数受到不同因素影响 位置不一样发行版本 或者debug x86 x64 编译器版本都有可能影响main 函数位置纯真(老)版本 入口点
[*]push
[*]push
[*]

[*]push
[*]call
入口点位置 fastcall 约定(在以前记录里能找到)RCXRDX R8入口点
怎么找main 函数 使用的实验代码我使用vs2015 版本的 代码 (MTD) 进行逆向#include <stdio.h>
#include <stdlib.h>
int main() {
    printf("hello,world");
    system("pause");
    return 0;
}
​此代码拖入 ida 进行分析 直接进入main函数 (有).plb直接进入main_0界面 ; Attributes: thunk

; int __cdecl main_0(int argc, const char **argv, const char **envp)
_main_0 proc near

argc= dword ptr4
argv= dword ptr8
envp= dword ptr0Ch

jmp   _main
_main_0 endpjmp main 解释跳转到main 函数的地方 双击就可以非可视化界面 使用ctrl + "+"找到main 双击进入即可进入 主函数
__cdecl main_0但是 我们目的是什么 我们要探索该代码的规则 所以查看调用的 函数也就是__cdecl main_0使用交叉引用就可以 找到调用到上个 函数 快捷键位ctrl + x__cdecl invoke_main(); Attributes: library function bp-based frame

; int __cdecl invoke_main()
invoke_main proc near
push    ebp
mov   ebp, esp
call    j___get_initial_narrow_environment
push    eax             ; envp
call    j____p___argv
mov   eax,
push    eax             ; argv
call    j____p___argc
mov   ecx,
push    ecx             ; argc
call    _main_0 ;<---- 这个就是上个main_0 函数
add   esp, 0Ch
pop   ebp
retn
invoke_main endp
​一共三个 call 第三个 call就是mian _0 我在注释上写 了 但是咱们不是往深处找 往 回找 找到最初的路线 cdecl invoke_mai 就是咱们要找的 点击进去然后 继续使用交叉引用跳转到invoke main 这里 就是刚才的入口 然后发现太麻烦了 可以选择变成普通模式空格键可以变普通模式FTP & _scrt_common_main_seh函数                               add   esp, 4
.text:00450EE6               movzx   eax, al
.text:00450EE9               test    eax, eax
.text:00450EEB               jz      short loc_450EFB
.text:00450EED               mov   ecx,
.text:00450EF0               mov   edx,
.text:00450EF2               push    edx             ; _Callback
.text:00450EF3               call    j___register_thread_local_exe_atexit_callback
.text:00450EF8               add   esp, 4
.text:00450EFB
.text:00450EFB loc_450EFB:                           ; CODE XREF: __scrt_common_main_seh+128↑j
.text:00450EFB                                       ; __scrt_common_main_seh+13B↑j
.text:00450EFB               call    invoke_main; main函数这里是个特殊的代码区 没有第二个 通过指令判断 这是什么 ? --> C++程序启动和线程局部存储(Thread Local Storage, TLS)向上翻找到特殊的关键字看到main 的时候__scrt_common_main__scrt_common_main_seh proc near      ; CODE XREF: __scrt_common_main+8↑p   
.text:00450DB0
.text:00450DB0 var_40          = dword ptr -40h
.text:00450DB0 var_3C          = dword ptr -3Ch
.text:00450DB0 var_38          = dword ptr -38h
.text:00450DB0 return_code   = dword ptr -34h
.text:00450DB0 xcptnum         = dword ptr -30h
.text:00450DB0 main_result   = dword ptr -2Ch
.text:00450DB0 Target          = dword ptr -28h
.text:00450DB0 tls_dtor_callback= dword ptr -24h
.text:00450DB0 tls_init_callback= dword ptr -20h
.text:00450DB0 is_nested       = byte ptr -1Ah
.text:00450DB0 has_cctor       = byte ptr -19h
.text:00450DB0 ms_exc          = CPPEH_RECORD ptr -18h
.text:00450DB0
.text:00450DB0 ; __unwind { // __except_handler4
.text:00450DB0   继续交叉引用   跳转到这里 这个函数 scrt_common_main()scrt_common_main proc near            ; CODE XREF: _mainCRTStartup+3↓p
.text:00450D90               push    ebp
.text:00450D91               mov   ebp, esp
.text:00450D93               call    j____security_init_cookie
.text:00450D98               call    __scrt_common_main_seh;<--- 刚才那个函数上面那个的call 入口
.text:00450D9D               pop   ebp
.text:00450D9E               retn
.text:00450D9E __scrt_common_main endp这个第二个call 就是 根据 scrt_common_main 反向推 继续交叉引用 你会寻找到唯一的call __scrt_common_main这就是刚才的入口继续找\mainCRTStartup()mainCRTStartup proc near               ; CODE XREF: start_1↑j
.text:004510B0               push    ebp
.text:004510B1               mov   ebp, esp
.text:004510B3               call    __scrt_common_main
.text:004510B8               pop   ebp
.text:004510B9               retn
.text:004510B9 _mainCRTStartup endp这个是真正的入口点 vs 编译的入口点真正的入口点 mainCRTStartup然后继续往上推进 交叉引用 就会找到第一层        int __cdecl start_1().text:0044A730
.text:0044A730 ; int __cdecl start_1()
.text:0044A730               public start_1
.text:0044A730 start_1         proc near
.text:0044A730               jmp   _mainCRTStartup
.text:0044A730 start_1         endp
.text:0044A730哎 你再交叉引用 你就没了这就是第一层了 没了我的历史写的 也许不太好但是可以借鉴一下

Kuukyaku 发表于 2024-11-15 10:29

如果用ida的话,它加载完一个程序会自动跳到它判断的入口点,一般是main或WinMain,不知道它是不是这样判断的

BGDK111 发表于 2024-11-16 04:43

Kuukyaku 发表于 2024-11-15 10:29
如果用ida的话,它加载完一个程序会自动跳到它判断的入口点,一般是main或WinMain,不知道它是不是这样判断 ...

这是如何手动寻找的原理

冥界3大法王 发表于 2024-11-18 07:09

那个api是叫loadmodule 吧?有点印象得查一查

冥界3大法王 发表于 2024-11-18 23:11

是的,还漏说了两
页: [1]
查看完整版本: 如何找到入口点