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

静态链接库

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\n",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\n",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\n",a,b,c,d);
	return 0;
}


posted @ 2020-03-30 22:35  程序媛墨禾  阅读(567)  评论(0编辑  收藏  举报