본문 바로가기

Programming

Windows Library Structure

리눅스의 libc 라이브러리 같은 경우 내부에 자체적으로 시스템콜 명령까지

가지고있지만 Windows 의 C Runtime 라이브러리(C 언어의 기본 함수들을 구현하기위한

라이브러리) 같은경우 내부적으로 다시 Windows NT 의 kernel32.dll 과 같은 라이브러리 

함수를 호출하게 되어있다.


따라서 msvcrt.dll 과 같은 MS C Runtime 라이브러리를 PE에 statically link 하더라도

그 내부에서는 다시 shared lib 인 kernel32.dll 로 진입하게 된다.

이때문에 리눅스처럼 gcc -o a a.c -static 으로 컴파일한다음

strip 을 하는 그런 방식의 심볼제거가 windows 에서 할수가 없다

궁금한점은 kernel32.dll 과 같은 라이브러리도 static 하게 링크시킬수 있는가? 인데...

아래의 질문에 대한 답에 따르면 결론은 Windows 의 경우 XP, 7, 8 뿐만아니라 모든 서비스팩마다도

시스템콜 넘버링이 다르기때문에 이론상 시스템콜 진입까지 static 하게 할수있지만

사실상 그렇게 하기 어려운 것이었다.

리눅스의 경우 consistent system call numbering 을 하는반면

윈도우즈의 경우 시스템콜 넘버링이 가변적이라는것이 가장 핵심적인 차이이다.


아래의 문서내용들을 잘 참고할것.


http://stackoverflow.com/questions/2766233/what-is-the-c-runtime-library

http://stackoverflow.com/questions/7705869/static-libraries


결과적인 나의 질문


I have compiled following C source code in VS2010 console project.

#include <stdio.h>
int main(int argc, char* argv[]){
    printf("hello world\n");
    return 0;
}

then I used /MT option for release mode to statically link the C-runtime library. however, as far as I know, C-runtime library still invokes the Windows NT library for example, C-runtime function 'printf' eventually calls 'WriteFile' Windows API.

and the actuall function body of 'WriteFile' is in 'kernel32.dll' shared library. so, even if I link the C-runtime library statically, the EXE binary doesn't contain the entire routine including the SYSENTER, or INT 0x2E instructions... the rest core part is still shared library... the following picture describes what I understand...

enter image description here

what I want is to statically link EVERYTHING into single EXE file. including kernel32.dll, user32.dll to eliminate the necessity of loader parsing the IAT and resolving the function names.

the following picture describes what I want...

enter image description here

I understand this is simple in Linux gcc. all I have to do is give the option -static

is there any option like this in VS2010? please correct me if I'm misunderstanding.

thank you in advance.




답변


The Windows kernel, unlike Linux or OS X, does not use consistent syscall numbering across versions. The numbers can change even after a servicepack release. For example, the NtReadFile syscall was0x0086 on Windows NT 4 but on Windows 7 it's 0x0111 (see here for the full list). That's why all proper programs use the kernel32.dll (or ntdll.dll) to perform the actual call - these DLLs are guaranteed to use the syscall numbers matching the kernel.

By the way, you won't save anything by not listing kernel32.dll in your IAT - it's always mapped into the process by the system loader (starting from Windows 2000 IIRC).


'Programming' 카테고리의 다른 글

Android APK Decompile  (0) 2013.05.24
Difference between Ntxxx and Zwxxx API  (0) 2013.05.22
netcat proxy  (1) 2013.04.24
Android Rootkit  (0) 2013.04.24
Android rootkit developing environment  (0) 2013.04.23