• 逆向笔记——静态链接库 动态链接库


    静态链接库

    OD查看模块,没有 TestStaticLib.lib 模块

    OD 查看汇编,找到Plus方法,发现 静态链接库编译在调用它的exe中,并没有实现真正的模块化

    Plus方法

    代码

    编译lib

    stdafx.h

    #ifndef __LIB_H__
    #define __LIB_H__
    
    int Plus(int x,int y);
    int Sub(int x,int y);
    int MutiPl(int x,int y);
    int Divide(int x,int y);
    
    #endif
    

    stdafx.cpp

    #include "stdafx.h"
    
    
    int Plus(int x,int y)
    {
    	return x+y;
    }
    int Sub(int x,int y)
    {
    	return x-y;
    }
    int MutiPl(int x,int y)
    {
    	return x*y;
    }
    int Divide(int x,int y)
    {
    	if(y!=0)
    		return x/y;
    	return 0;
    }
    

    把.lib文件放在新工程目录下,调用lib

    main.cpp

    #include <stdio.h>
    #include "stdafx.h"
    #pragma comment(lib,"TestStaticLib.lib")
    
    int main(int argc, char* argv[])
    {
    	printf("%d
    ",Plus(1,2));
    	return 0;
    }
    

    动态链接库

    关键字解读

    extern

    C :按C编译,编译后的函数名用Depends打开如下:

    __declspec(dllexport)告诉编译器此函数为导出函数;

    lib代码

    MyDll.h

    #if !defined(AFX_STDAFX_H__6DE6F869_445D_43BA_A4B8_8DD48F71F80A__INCLUDED_)
    #define AFX_STDAFX_H__6DE6F869_445D_43BA_A4B8_8DD48F71F80A__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    extern "C" _declspec(dllexport) __stdcall int Plus(int x,int y); //extern :全局函数,可以供各个函数调用
    extern "C" _declspec(dllexport) __stdcall int Sub(int x,int y);  //C 按照C语言方式进行编译、链接
    extern "C" _declspec(dllexport) __stdcall int Mul(int x,int y);  //_declspec(dllexport) 告诉编译器这是导出函数
    extern "C" _declspec(dllexport) __stdcall int Div(int x,int y);
    
    #endif 
    

    MyDll.cpp

    #if !defined(AFX_STDAFX_H__6DE6F869_445D_43BA_A4B8_8DD48F71F80A__INCLUDED_)
    #define AFX_STDAFX_H__6DE6F869_445D_43BA_A4B8_8DD48F71F80A__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    extern "C" _declspec(dllexport) __stdcall int Plus(int x,int y); //extern :全局函数,可以供各个函数调用
    extern "C" _declspec(dllexport) __stdcall int Sub(int x,int y);  //C 按照C语言方式进行编译、链接
    extern "C" _declspec(dllexport) __stdcall int Mul(int x,int y);  //_declspec(dllexport) 告诉编译器这是导出函数
    extern "C" _declspec(dllexport) __stdcall int Div(int x,int y);
    
    #endif 
    

    两种调用方式

    方式一:隐式连接

    步骤1:将 *.dll *.lib 放到工程目录下面

    步骤2:将 #pragma comment(lib,"DLL名.lib") 添加到调用文件中

    步骤3:加入函数的声明

    extern "C" __declspec(dllimport) __stdcall int Plus (int x,int y);
    extern "C" __declspec(dllimport) __stdcall int Sub (int x,int y);
    extern "C" __declspec(dllimport) __stdcall int Mul (int x,int y);
    extern "C" __declspec(dllimport) __stdcall int Div (int x,int y);

    说明:

    __declspec(dllimport)告诉编译器此函数为导入函数;

    代码
    StdAx.h

    #if !defined(AFX_STDAFX_H__2846F71E_C0E2_4634_94E9_857285842867__INCLUDED_)
    #define AFX_STDAFX_H__2846F71E_C0E2_4634_94E9_857285842867__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    extern "C" __declspec(dllimport) __stdcall int Plus (int x,int y);  						
    extern "C" __declspec(dllimport) __stdcall int Sub (int x,int y);						
    extern "C" __declspec(dllimport) __stdcall int Mul (int x,int y);						
    extern "C" __declspec(dllimport) __stdcall int Div (int x,int y);						
    
    #endif // !defined(AFX_STDAFX_H__2846F71E_C0E2_4634_94E9_857285842867__INCLUDED_)
    
    

    TestLib.cpp

    // StaticLib.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <stdio.h>
    #pragma comment(lib,"TestDynLib2.lib")
    
    int main(int argc, char* argv[])
    {
    	printf("%d
    ",Plus(1,2));
    	return 0;
    }
    

    方式二:显示链接

    步骤1: //定义函数指针
    typedef int (__stdcall *lpPlus)(int,int);
    typedef int (__stdcall *lpSub)(int,int);
    typedef int (__stdcall *lpMul)(int,int);
    typedef int (__stdcall *lpDiv)(int,int);

    步骤2: //声明函数指针变量
    lpPlus myPlus;
    lpSub mySub;
    lpMul myMul;
    lpDiv myDiv;

    步骤3: //动态加载dll到内存中
    HINSTANCE hModule = LoadLibrary("DllDemo.dll");

    步骤4: //获取函数地址
    myPlus = (lpPlus)GetProcAddress(hModule, "_Plus@8");
    mySub = (lpSub)GetProcAddress(hModule, "_Sub@8");
    myMul = (lpMul)GetProcAddress(hModule, "_Mul@8");
    myDiv = (lpDiv)GetProcAddress(hModule, "_Div@8");

    步骤5: //调用函数
    int a = myPlus(10,2);
    int b = mySub(10,2);
    int c = myMul(10,2);
    int d = myDiv(10,2);

    特别说明:

    Handle 是代表系统的内核对象,如文件句柄,线程句柄,进程句柄。

    HMODULE 是代表应用程序载入的模块

    HINSTANCE 在win32下与HMODULE是相同的东西 Win16 遗留

    HWND 是窗口句柄

    其实就是一个无符号整型,Windows之所以这样设计有2个目的:

    1、可读性更好

    2、避免在无意中进行运算

    代码
    TestLib.cpp

    // StaticLib.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <stdio.h>
    #include <windows.h>	
    
    typedef int (__stdcall *lpPlus)(int,int);					
    typedef int (__stdcall *lpSub)(int,int);					
    typedef int (__stdcall *lpMul)(int,int);					
    typedef int (__stdcall *lpDiv)(int,int);	
    
    int main(int argc, char* argv[])
    {
    	lpPlus myPlus;					
    	lpSub mySub;					
    	lpMul myMul;					
    	lpDiv myDiv;
    
    	HINSTANCE   hModule = LoadLibrary("TestDynLib2.dll"); 
    
    	myPlus = (lpPlus)GetProcAddress(hModule,   "_Plus@8");					
    	mySub = (lpSub)GetProcAddress(hModule,   "_Sub@8");					
    	myMul = (lpMul)GetProcAddress(hModule,   "_Mul@8");					
    	myDiv = (lpDiv)GetProcAddress(hModule,   "_Div@8");	
    
    	int a = myPlus(10,2);					
    	int b = mySub(10,2);					
    	int c = myMul(10,2);					
    	int d = myDiv(10,2);	
    
    	printf("%d,%d,%d,%d
    ",a,b,c,d);
    	return 0;
    }
    
    
    
  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——117
    《那些年啊,那些事——一个程序员的奋斗史》——116
    《那些年啊,那些事——一个程序员的奋斗史》——116
    《那些年啊,那些事——一个程序员的奋斗史》——118
    《那些年啊,那些事——一个程序员的奋斗史》——119
    《那些年啊,那些事——一个程序员的奋斗史》——117
    《那些年啊,那些事——一个程序员的奋斗史》——119
    283. Move Zeroes
    26. Remove Duplicates from Sorted Array
    268. Missing Number
  • 原文地址:https://www.cnblogs.com/Erma/p/12599460.html
Copyright © 2020-2023  润新知