VC에서 생성된 PE 정보(exe, dll, sys...)파일의 함수 이름 손질
4753 단어 dll
(1) 내보낼 함수 서명(signature)에 키워드 추가declspec(dllexport)
예를 들면 다음과 같습니다.
void __declspec(dllexport) _cdecl someFun()
{
printf("Hello, World!
");
}
이 방법을 사용하여 내보낸 함수, 함수의 이름 코스메틱, 기본 코스메틱 방법:
(1).1 따르면.c 파일에서 내보내면 함수 호출 규칙과 관련된 c 언어의 이름 코스메틱 규칙이 사용됩니다.
① _cdecl/__cdecl (c 호출 약정): 내보낼 함수 이름은someFun이고, 이름은 다음과 같습니다: someFun. 즉, 이 호출 약정에서 원 함수 이름과 수식 이름은 대소문자를 포함하여 동일합니다.
② _stdcall/__stdcall (표준 호출 약정): 내보낼 함수 이름은someFun이고, 이름 수식 후: _someFun@0, 즉 이름 수식 규칙은: 원 함수 이름 앞에 밑줄 넣기 (),원래 함수 이름 뒤에at 기호 (@) 를 붙이고, 마지막으로 이 함수가 설명하는 형식의 매개 변수의 형식이 차지하는 바이트의 총계를 따라갑니다.
③ _fastcall/__fastcall (레지스터 참조 약정): 내보낼 함수 이름은someFun이고, 이름은 다음과 같습니다: @someFun@0, 즉 그 이름 수식 규칙은: 원래 함수 이름의 앞과 뒤에 각각at 기호 (@) 를 붙이고, 마지막으로 이 함수가 성명한 형식의 매개 변수의 유형이 차지하는 바이트의 총계이다.
(1).2 따르면.cpp 파일에서 내보내는 것은 c++ 언어의 명칭 수식 규칙을 사용하는데 그 규칙은 함수의 호출 약정과 관련이 있다. 그 명칭 수식은 함수의 호출 약정, 함수 매개 변수 유형, 함수 반환 값 유형, 함수의 역할 영역(전역 함수, 클래스의 구성원 함수) 등과 관련이 있으며 구체적으로 MSDN을 참고한다.
팁: C++ 글로벌 함수 이름 손질에 대한 빠른 식별 방법:
① _cdecl/__cdecl: ?functionname@@YA ......
② _stdcall/__stdcall: ?functionname@@YG ......
③ _fastcall/__stdcall: ?functionname@@YI ......
(1).3 컴파일 방법:
① cl/LD filename.c[pp] ------>filename.lib and filename.dll
② cl/c filename.c[pp] --->filename.obj
link/dll filename.obj ---->filename.lib and filename.dll
(2) 사용한다.def 파일 방식으로 함수 내보내기
함수의 서명(signature)이 정상적으로 작성되어 을 추가할 필요가 없습니다.declspec(dllexport),
예를 들면 다음과 같습니다.
void _cdecl someFun()
{
printf("Hello, World!");
}
원본 파일을 작성한 후에 또 하나를 작성해야 한다.def 파일의 작성 방법은 다음과 같습니다.
LIBRARY Fun3
EXPORTS
SomeFun1 = somefun1
SomeFun2 = somefun2@0
SomeFun3 = @somefun3@0
이상의 내용을 하나로 저장합니다.def 파일(예: mydll.ff, 그중의Fun3은 dll 파일의 파일 이름입니다. EXPORTS 문장은 함수를 내보내기 위해 별명을 붙일 수 있습니다. 그 방법은 위와 같습니다. 별명 = 함수의 수식명 (내부명) 은 이름을 바꿀 수 있고 DLL을 사용하면 다른 언어로 작성된 순서에 사용할 수 있습니다. (기호가 일치합니다.)
컴파일 방법:
① cl/LD filename.c[pp]/link/DEF:mydll.def
② cl/c filename.c[pp]
link/DEF:mydll.def filename.obj ------>filename.dll and filename.lib
2. DLL 파일에서 내보낸 함수를 사용하는 방법:
① DLL 파일을 생성할 때 함수 서명이 있는 헤더 파일(.h 파일)이 있으면include를 원본 파일(#include "filename.h")로 가져오면 원본 파일에서 직접 사용할 수 있습니다.h에서 내보내는 함수 이름, 프로그램이 컴파일된 후 연결할 때 dll에 대응하는lib 파일을 연결해야 합니다!!
② 헤더 파일 없음: 다음 설명을 사용합니다.
void __declspec(dllimport) _cdecl funcationname();
주의: 함수의 서명은 함수를 내보낼 때의 서명과 완전히 일치해야 합니다. 호출 약정,static,const 수식 등을 포함하고 도 추가해야 합니다.declspec(dllimport) 키워드, 프로그램이 컴파일된 후 연결할 때 dll에 대응하는lib 파일을 연결합니다!!
③ LoadLIbrary를 사용하여 동적으로 로드
3. extern "C"정보
c 언어는 c++ 언어의Name Decoration 규칙과 다르기 때문에 C 언어로 작성된 DLL을 c++ 프로그램에서 사용할 수 있도록 함수를 내보낼 때 extern "C"를 붙여서 C의 이름 수식을 표시해야 기호를 정확하게 찾을 수 있고 함수를 정확하게 호출할 수 있습니다.
예를 들면 다음과 같습니다.
//filename.cpp
extern "C"void __declspec(dllexport) __cdecl somefun1()
{
printf("Hello, World!");
}
참고: 이 함수를 사용할 경우 void 로 선언됩니다.declspec(dllimport) __cdecl somefun1();
필요없어도 extern "C"를 추가할 수 없습니다!!!!
4. PE의 함수 기호 문제
PE 파일의 가져오기 테이블에는 해당 PE 파일에 사용된 모든 외부 기호(다른 DLL 파일에서 내보낸 함수 기호)가 저장되어 있습니다. 이름 수정을 거친 기호입니다. 구체적인 기호 형식은 1의 내용으로 알 수 있습니다. DLL 파일의 내보내기 테이블에는 이 DLL의 도출 함수가 저장되어 있는 기호, DLL 로더,이러한 기호에 따라 함수의 정보(함수 이름, 함수의 가상 주소)를 포지셔닝한 다음에 다시 포지셔닝하는 것이다.
5.COM(Component Object Module)의Create형 함수는 종종 extern "C"와 로 성명된다cdecl, 이렇게 하면 함수가 2진 파일로 컴파일될 때, 그 이름이 수식된 함수의 이름이 여전히 원 함수 이름임을 보장합니다.COM의 이진 수준의 언어와 무관성과 인터페이스와 분리된 특성을 실현하였습니다!!
dll로 클래스를 내보내는 것은 사실상 클래스를 내보내는 방법일 뿐이다.(이름으로 꾸미기)
6.dll에서 데이터 내보내기
6.1에서 일반 데이터
dll에서 내보낼 때declspec(dllexport) 내보낼 변수를 수정하고 사용할 때declspec(dllimport)로 변수를 손질합니다. 예를 들면 다음과 같습니다.
//some.dll
__declspec(dllexport) int a = 0;
클라이언트가 사용할 때:some를 생성합니다.dll에서 가져온 라이브러리 파일 soem.lib 클라이언트 프로그램에 연결
__declspec(dllimport) int a;
6.2에서 공유 데이터 내보내기(dll에 공유 세그먼트 만들기)
#pragma data_seg(".shared")
__declspec(dllexport) int a = 0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared, RWS")
코드를 사용하여 dll에 공유 세그먼트를 만들고 이 세그먼트에 공유 변수 a를 내보냅니다
클라이언트에서 사용 가능declspec(dllimport) int a;를 참고하십시오.
참고: RWS 속성이 있는 세그먼트를 만들 때는 변수를 초기화해야 합니다. 그렇지 않으면 세그먼트를 만드는 데 실패하고 컴파일되지 않습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
LoadLibrary에서 126 오류가 발생하면 원인이되는 파일 이름을 찾는 방법Loadlibrary에서 DLL을 동적으로 로드할 때 로드 실패입니다. 실패한 파일 이름은 알려주지 않습니다. 로드하고자 하는 DLL 자체를 로드할 수 없다면 이야기는 간단하지만, 대상 DLL이 다른 DLL을 로드하...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.