본문 바로가기
개발 및 운영

libeay32.dll/ssleay32.dll LoadLibrary시 ERROR_INVALID_ADDRESS(487)오류나는 경우

by Joseph.Lee 2019. 5. 17.

openssl를 fips로 빌드한 경우 해당 libeay32.dll / ssleay32.dll / libeay64.dll / ssleay64.dll 를 LoadLibrary으로 로드하느 경우(그냥 로드하든지 어찌되었든..) ERROR_INVALID_ADDRESS (487)오류가 나는 경우가 있다.

 

이러한 경우 해당 DLL를 사용하는 Exe파일을 빌드할 때 Visual Studio에서

 

링커 -> 일반 -> 증분 링크 사용 : 아니요

 

으로 설정하면 해결된다.

 

이는 fips의 경우 고정된 메모리 위치에 dll이미지를 로드해서 내부적으로 파일 변조 여부를 파악하게 되는데

 

증분링크기능을 사용하면 그 부분에서 뭔가 꼬이는 것 같다.

 

추가적으로 전에 7z.dll을 사용할 경우도 있었는데 libeay32.dll보다 7z.dll를 먼저 로드하면 7z.dll이 libeay32.dll이 점유해야할 메모리 위치에 먼저 로드되서 openssl이 로드되지 않는 경우또한 있었다.

 

추가적으로 ssleay32.dll이 libeay32.dll보다 먼저 로드하는 경우에도 이런 경우가 생기기도 한다.

 

이런 경우는 아마 libeay32.dll, ssleay32.dll를 지연된 DLL로드로 로드하는 경우일텐데

 

dll를 로드해야 하는 경우

OpenSSL_add_all_algorithms(); // 먼저
SSL_library_init(); // 이후

 

이렇게 코드를 사용하면 자연스래 libeay먼저 로드되고 이후 ssleay가 로드된다.

 

(근데 이렇게까지 해도 가끔 저 오류가;;;;;)

 

 

---

 

VMMap 란 프로그램으로 프로그램 맵을 보면 로드하려는 주소의 사용여부를 알 수 있다.

 

libeay32.dll의 로드주소는 0x0FB00000 인데 저 오류가 뜰 때 보면 이미 해당 주소를 사용중일 것이다.

 

근데 참 골때리는 경우는... 다른 DLL이 해당 주소를 차지하면 그건 먼저 로드하면 해결이 되는데..

 

애초에 프로그램 시작 시 HEAP등으로 자동으로 잡아버리는 경우이다...

 

우짜지...?ㅠㅠㅠㅠ

 

---

 

해결방법을 찾앗따!!!!

 

문제는 Delayed load때문이었다...ㅠㅠ OS가 멍청하지 않은 이상 초기 Loader가 DLL의 Load Address를 확인치 않고 메모리를 할당하진 않겠지!

 

Delayed Load하지 않고 바로 로드하도록 하니 문제는 해결되었다..

 

만약 직접 빌드하는 프로그램이 아닌 다른 프로그램 (예 electron.exe)인 경우에는

 

LoadPE으로 Import Directory 를 수정해서 libeay32.dll을 추가해주면 된다.

 

LoadPE에 해당 DLL의 함수이름을 써줘야 하는대 대충 OpenSSL_load_all_ciphers 이걸 추가해주었더니 잘 된다~

반응형

댓글