TOMCAT_HOME/lib/el-api.jar 


파일을


JAVA_HOME/jre/lib/ext 폴더에 복사




'레퍼런스 > API' 카테고리의 다른 글

[winAPI] ReadProcessMemory  (1) 2013.09.14
[winAPI] ProcessToken, AccessToken  (0) 2013.09.12
[winAPI]GetModuleFileName 함수  (0) 2013.09.02
[winAPI] DllMain 정의  (0) 2013.09.02
[winAPI] ListBox 여러개 삭제, 멀티 셀렉트 삭제  (0) 2012.05.30
Posted by $Zero
:
BOOL WINAPI ReadProcessMemory(
  _In_   HANDLE hProcess,
  _In_   LPCVOID lpBaseAddress,
  _Out_  LPVOID lpBuffer,
  _In_   SIZE_T nSize,
  _Out_  SIZE_T *lpNumberOfBytesRead
);

Process의 메모리 데이터를 읽어오는 함수.


hProcess : 메모리에서 데이터를 읽어 올 프로세스의 핸들. 이 핸들에대한 PROCESS_VM_READ 권한이 있어야 메모리에 액세스 할 수 있다. (디버깅 모드로 접근시 모든 메모리에대해 R/W 권한이 있다.)

lpBaseAddress : 읽어올 데이터가 있는 메모리의 주소. 이 메모리의 주소는 hProcess내의 공간이어야 하며, 시스템은 이 메모리에 접근해 데이터를 전송하기전에 이 메모리를 읽을 권한이 있는지 검사하고 혹 권한이 없다면 함수를 종료한다.

lpBuffer : lpBaseAddress에 있는 데이터를 받기위한 버퍼의 포인터 . 

nSize : 받을 데이터의 크기 


lpNumberOfBytesRead : 받아온 데이터의 크기를 저장할 변수의 포인터. 

(NULL로 지정시 이 파라미터는 무시된다.)


Posted by $Zero
:



Token관련 API 

Windows의 Token은 계정의 권한과 같은 개념이다. 

윈도우엔 권한이 있어야만 실행 가능한 것들이 있다.

(현재 로그인 세션의 권한을 저장하고 있는 변수라고 생각하면 된다.)


BOOL WINAPI OpenProcessToken(
  _In_   HANDLE ProcessHandle,
  _In_   DWORD DesiredAccess,
  _Out_  PHANDLE TokenHandle
);

ProcessHandle : Token을 얻어올 프로세스 핸들
DesiredAccess : 해당 프로세스에서 필요한 액세스 권한
TokenHandle : 얻어온 토큰이 저장될 핸들


BOOL WINAPI LookupPrivilegeValue(
  _In_opt_  LPCTSTR lpSystemName,
  _In_      LPCTSTR lpName,
  _Out_     PLUID lpLuid
);

*LUID = locally unique identifier의 약자로 Windows가 부팅되면서 부여되는 64비트크기의 고유한 값이다.


함수 이름 그대로 PrivilegeValue 값을 Lookup하는 함수. 
PrivilegeValue는 LUID로 구분되어 OS가 리부팅 되기전까지 가지고 있는 고유한 값이다.
(각 권한마다 매 부팅시 LUID가 부여되며 우리는 이 LUID로 권한을 disable || enable 시킬 수 있는 것이다.)


lpSystemName : Privilege값을 얻어올 시스템 이름. NULL입력시 로컬 시스템.
(MSDN에서 의미하는 System이 호스트단위인지는 잘 모르겠다. 공유가 가능한 LAN상에서 타 시스템의 Token도 가지고 올 수 있는건지 MSDN에선 Local system과 일반 system을 구분하고 있다.)

lpName : PrivilegeValue를 얻어올 PrivilegeName. 

lpLuid : PrivilegeValue를 받을 LUID자료형의 포인터. 



BOOL WINAPI AdjustTokenPrivileges(
  _In_       HANDLE TokenHandle,
  _In_       BOOL DisableAllPrivileges,
  _In_opt_   PTOKEN_PRIVILEGES NewState,
  _In_       DWORD BufferLength,
  _Out_opt_  PTOKEN_PRIVILEGES PreviousState,
  _Out_opt_  PDWORD ReturnLength
);

명시된 Access Token 의 권한을 Disable || Enable 시킬 수 있는 API함수


TokenHandle : 권한을 수정 할 Token의 핸들.

DisableAllPrivileges : 수정과는 관계없는 인자이므로 FALSE를 전달하면 된다. 이 값이 TRUE일 경우 NewState값은 무시되며 모든 권한이 Disable된다 

NewState : 수정할 토큰에대한 정보를 담은 TOKEN_PRIVILEGES 구조체의 포인터 (예제 참조)

BufferLength : 버퍼의 크기 입력. 수정되기전의 Privileges 값을 받을 때 사용되는 버퍼같은데 어떻게 사용하는지는 자세하게 알지 못하겠다. 0으로 설정하려면 PreviousState (변경되기 전의 값을 받을 포인터) 또한 NULL이어야 한다. 

PreviousState : 변경되기전 Privileges값을 받기위한 포인터 

ReturnLength : 변경되기전 Privileges 값을 리턴받기위해 필요한 바이트 크기. TOKEN_PRIVILEGES의 크기를 말하는 것 같다. 이 역시 PreviousState값이 NULL일 경우에만 NULL을 전달 할 수 있다. 




예제


int main(int argc, char *argv[])
{


if(!SetPrivilege(SE_DEBUG_NAME, TRUE))
return 1;

return 0;
}



BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;

if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{  
printf("OpenProcessToken error : %u\n", GetLastError());
return FALSE;
}

if(!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
{
printf("LookupPrivilegeValue error : %u\n", GetLastError());
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if(bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
else
tp.Privileges[0].Attributes = 0;               // disable

if(!AdjustTokenPrivileges(hToken, 
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD)NULL))
{
printf("AdjustTokenPrivileges error : %u\n", GetLastError());
return FALSE;
}

if(GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}

return TRUE;
}




**  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY 에 대해 


TOKEN_ADJUST_PRIVILEGES : Token에 Access권한을 설정하는 AdjustTokenPrivileges를 호출할때 필요하다
MSDN : Required to enable or disable the privileges in an access token.


TOKEN_QUERY : 어떤 값인지 감을 못잡겠다 . 

MSDN의 내용대로라면 Lookup API를 쓰기위해 지정해주는 mask가 아닐까 한다. 

query : 질의, 문의 

MSDN : Required to query an access token.

Posted by $Zero
:

GetModuleFileName 함수는 현재 실행되고 있는 프로세스의 이름을 얻어오는 함수이다. 


MSDN에 정의된 GetModuleFileName API


DWORD WINAPI GetModuleFileName(
  _In_opt_  HMODULE hModule,
  _Out_     LPTSTR lpFilename,
  _In_      DWORD nSize
);


첫 번째 인자는 이름을 얻어올 프로세스의 핸들이지만, 보통 자신의 이름을 얻기 위해 사용되므로 

NULL로 사용되는 경우가 대부분이다.  첫 번째 인자에 NULL을 넣어 사용하면 현재 자신의 이름을 얻어오고

그 외 다른 프로세스의 핸들을 전달하거나 DLL파일의 핸들을 전달하면 해당 모듈의 파일 이름을 얻어온다. 


두 번째 인자는 해당 모듈의 이름이 입력될 버퍼를 넣어주면 되고 


세 번째 인자는 버퍼의 사이즈를 넣어주면 된다. (이런 사이즈인수는 대부분 버퍼오버플로우 공격을 하지 못하도록 하기 위함이라고 보면 된다. 그외 오버 플로우로 인한 버그의 소지도 예방할 수 있음.)

Posted by $Zero
:

DLL 코드 작성


DLL 코드에는 winMain 함수처럼


DllMain 콜백 함수가 정의 된다.


DllMain을 정의하지 않더라도 컴파일이 되는데, 이는 컴파일러가 내용이 텅 빈(empty) dummy code를 삽입하기 때문이다.


반드시 필요하지만 정의하지 않을경우 컴파일러가 Default DllMain을 삽입해준다는 소리다.



DllMain 함수의 모양은 아래와 같다.


BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
    switch(dwReason)
    {
    case DLL_PROCESS_ATTACH:
        break;

    case DLL_PROCESS_DETACH:
        break;

    }

    return TRUE;
}


일단 첫 번째  인자는 winMain의 hInstance와 같은 역할을 하는 DLL자신의 인스턴스이다.


두 번째 인자 dwReason은 DLL이 호출된 이유를 담고 있다. 위 Switch 문이 그 값에 해당한다.

DLL_PROCESS_ATTACH: DLL파일이 처음 프로세스에 로딩되었을 때 (ex : LoadLibrary() 호출)

DLL_PROCESS_DETACH: DLL파일이 프로세스에서 해제 되었을 때  (ex : FreeLibrary() 호출)

이 외에도 스레드 관련 값이 2개 더 있다. (MSDN 참조)





Posted by $Zero
:

count = SendMessage(hList, LB_GETSELCOUNT, 0, 0);

            SendMessage(hList, LB_GETSELITEMS, 100, (LPARAM)cursel);

            for(int i=count-1; i>-1; i--)

            {

                SendMessage(hList, LB_DELETESTRING, cursel[i],0);

            }


선택된 여러 셀들을 삭제하려면


LB_GETSELCOUNT메시지를 보내 현재 선택된 셀의 갯수를 구하고


LB_GETSELITEMS 메시지를 보내 선택된 셀들의 인덱스를 담고있는 배열을 받아야한다


GETSELITEMS 메시지는 LPARAM에 전달된 배열에 인덱스를 채워주고 리턴된다. 


그리고 for문을 돌며 삭제를 해야하는데 이 때 , 반드시 거꾸로 삭제를 진행해야만 한다.


총9개의 셀이 선택됐다면, 배열은 0~8번까지 차있고


배열의 인덱스 8부터 시작해서 0까지 참조후 삭제해야 정상적인 삭제가 이뤄진다. 


0부터 8까지 올림차순으로 삭제를 진행하면 정상적인 삭제가 이뤄지지 않는다. 


예를들어


리스트 박스의 1,2,3 번째 셀이 선택되어 있다면


1번 셀을 지웠을경우 2번 셀이 1번 셀의 자리로 이동된다. 


그 때문에 다음에 2번 셀을 지울때 3번 셀이 2번으로 이동되어있기 때문에 3번 셀이 지워지며 3번 셀을 지우려고하면 해당 데이터가 없는상황이 발생한다.


그러므로 listbox의 셀을 지울땐 반드시 거꾸로 진행해야 한다. 



Posted by $Zero
: