protobuf-net What Files Do I Need

프로그래밍 2014. 12. 16. 19:16 Posted by friday13th

protobuf-net can be used on multiple platforms, and many different builds are available.


In particular, though, there are 2 main uses:


- the "full" version, which includes as much type-model / runtime support as will work on your chosen platform

- the "core only" version, which includes just the fundamental reader/writer API and core objects


If you are on a rich framework like full .NET, the "full" version is entirely appropriate and will work fine.


However, if you are on a restricted framework (Silverlight, Phone 7, WinRT, etc) then many operations would either

be slow, or impossible. To address this, protobuf-net provides these frameworks with a "precompile" facility,

which moves all of the impossible / slow steps to a build-time operation, emitting a serialiation dll you

can reference and use (now very fast etc) from your chosen framework.


More information about the precompiler is here:

http://marcgravell.blogspot.co.uk/2012/07/introducing-protobuf-net-precompiler.html


protobuf-net also includes a utility for processing ".proto" files (the schema DSL used by multiple protobuf

implementations) into C# and VB.NET; this is the ProtoGen tool.


Neither precompile nor ProtoGen need to be deployed with your application.



So: what do I need?


example: running on .NET 4.0


solution: copy the files from Full\net30. Note that protobuf-net does not require any 4.0 features, so using "net30" will

give you all of protobuf-net including WCF support (which is the difference between "net20" and "net30").



example: running on Silverlight 4


option 1: copy the files from Full\sl4, and accept that it isn't quite as optimal as it could be - but perfectly fine

for light-to-moderate serialization usage.


option 2: copy the files from CoreOnly\sl4, and use "precompile" (in the Precompile folder) at build-time to generate

a serialization assembly (this also needs to be referenced and deployed from you application).


Additional:


Note that each framework contains 3 files:


- protobuf-net.dll  the library itself

- protobuf-net.xml  intellisense xml, used by thre IDE when developing

- protobuf-net.pdb debugging symbols, useful when debugging


Of these - the only one you **need** to deploy is the dll; the pdb may be useful for investigating crash reports. The

xml is used only by the IDE.


Folders:


cf20     compact framework 2.0

cf35     compact framework 3.5

ios          iPad/iPod/iPhone via MonoTouch

net11     regular .NET 1.1 (excluded generics)

net20        regular .NET 2.0 (excludes WCF hooks)

net30        regular .NET 3.0 or above (including 3.5, 4.0, 4.5, ...)

netcore45 windows store apps / windows runtime 4.5

portable     portable class library (phone 7, xna, silverlight)

sl4          silverlight 4 or above

wp71         windows phone 7.1

unity        specific to unity (avoids missing "interlocked" methods)


License:


The full license is shown separately, but boils down to "do what you like with it, don't sue me,

don't blame me if it goes horribly wrong, don't claim you wrote protobuf-net"


Finally:


All feedback welcome.

Visual Studio 6.0 acme setup 에러

프로그래밍 2011. 12. 13. 10:55 Posted by friday13th

Visual Studio 6.0 설치시 acme 설치를 찾을 수 없다는 에러메세지가 뜨면서 설치가 안되는 상황 발생시  대처방법

나같은 경우는 윈도우 2003 서버에 설치시 에러가 났다.


해결법

 E:\SETUP\ACMSETUP.EXE /T VS98ENT.STF /S E:\ /n "" /o "" /k "1000000000" /b 1 

 

D 는 각자의 설치파일이 있는 드라이브이고 
1000000000 이것은 시디키입니다.

각자의 환경에 맞게 드라이브명과 시디키를 수정 후 실행 하세요.

 

DNS Cache 캐시 도메인 조회

프로그래밍 2011. 6. 22. 17:07 Posted by friday13th

DNS 캐시에서 도메인이 존재하는지 아래 함수로 체크할 수 있다.


BOOL DoesExistInDNSCache(const char *szDomain)
{
 BOOL bFound = FALSE;
 HMODULE hMod = LoadLibrary("dnsapi.dll");
 if (hMod)
 {
  FN_DNS dns = (FN_DNS)GetProcAddress(hMod, "DnsGetCacheDataTable");
  if (dns)
  {
   DNSCACHEENTRY *pEntry = NULL;
   dns(&pEntry);
   while(pEntry)
   {    
    if (stricmp(pEntry->pszName, szDomain)==0)
    {
     bFound=TRUE;
     break;
    }
    
    pEntry= pEntry->pNext;
   }
  }
  FreeLibrary(hMod); 
 }
 return bFound;
}


도메인 캐시를 삭제하기 위해서는 커맨드창에서 ipconfig /flushdns 를 치면 된다.
도메인 캐시를 보기 위해서는 ipconfig /displaydns

로드된 드라이버 목록 가져오기

프로그래밍 2011. 6. 22. 16:38 Posted by friday13th
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define SystemModuleInformation 11
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
// SystemModuleInformation 구조체 선언
typedef struct _SYSTEM_MODULE_INFORMATION {
 ULONG Reserved[2];
 PVOID Base;
 ULONG Size;
 ULONG Flags;
 USHORT Index;
 USHORT Unknown;
 USHORT LoadCount;
 USHORT ModuleNameOffset;
 CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
int main(int argc, char* argv[])
{
 HMODULE ntdll_handle;
 FARPROC NtQuerySystemInformation;
 PVOID *module_num;
 SYSTEM_MODULE_INFORMATION *module;
 DWORD module_size;
 
 ntdll_handle = GetModuleHandleA("ntdll.dll");
 NtQuerySystemInformation = GetProcAddress(ntdll_handle, "NtQuerySystemInformation");
 
 // 로드된 모듈 갯수 가져오기
 module_num = (PVOID *)malloc(0x4);
 if(((int (__stdcall *)(DWORD, PVOID, ULONG, PULONG))NtQuerySystemInformation)(SystemModuleInformation, module_num, 0x4, NULL) != STATUS_INFO_LENGTH_MISMATCH) {
  printf("Not Loaded Module???\n");
  free(module_num);
  return 0;
 }
 
 
 // 로드된 모듈 모든 정보 가져오기
 module_size = sizeof(SYSTEM_MODULE_INFORMATION) * (int)*(PVOID *)module_num + 4;
 module = (SYSTEM_MODULE_INFORMATION *)malloc(module_size);
 SYSTEM_MODULE_INFORMATION* pmodule_backup = module;
 if(((int (__stdcall *)(DWORD, PVOID, ULONG, PULONG))NtQuerySystemInformation)(SystemModuleInformation, module, module_size, NULL) < 0) {
  printf("Error\n");
  free(module_num);
  free(module);
  return 0;
 }
 
 // 로드된 모듈 정보 출력
 module = (SYSTEM_MODULE_INFORMATION *)((char *)module + 4);
 for (int i=0; i<(int)*(PVOID *)module_num; i++) {
  printf("%8x %9x %9x %3x %3x %3x %3x  %-20s\n",\
   module->Base,\
   module->Size,\
   module->Flags,\
   module->Index,\
   module->Unknown,\
   module->LoadCount,\
   module->ModuleNameOffset,\
   module->ImageName+module->ModuleNameOffset);
  module += 1;
 }
 
 free(module_num);
 free(pmodule_backup);
// getchar();
 return 0;
}
 

프로세스 숨기기 (XP)

프로그래밍 2011. 6. 22. 16:35 Posted by friday13th
예제

#include "stdafx.h"
#include <malloc.h>
#include <windows.h>
//NTSTATUS값이 0이상이면 보통 성공한 상태를 의미한다
#define NT_SUCCESS(Status)    ((NTSTATUS)(Status) >= 0)
//사이즈를 잘못 맞춘 경우
#define STATUS_INFO_LENGTH_MISMATCH  ((NTSTATUS)0xC0000004L)
//NT함수가 사용하는 리턴 값인 NTSTATUS는 LONG형으로 정의된다
typedef LONG       NTSTATUS;
//원래 값이 엄청 많다
//16은 레퍼런스에는 나와있지 않은 값인데,
//이를 넣을 경우 SYSTEM_HANDLE_INFORMATION을 얻을 수 있다
typedef enum _SYSTEM_INFORMATION_CLASS
{
 SystemHandleInformation = 16
} SYSTEM_INFORMATION_CLASS;
//시스템 핸들에 대한 정보를 가지고 있다
typedef struct _SYSTEM_HANDLE_INFORMATION
{
 ULONG   ProcessId;
 UCHAR   ObjectTypeNumber;
 UCHAR   Flags;
 USHORT   Handle;
 PVOID   Object;
 ACCESS_MASK  GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
//가상 메모리에 데이터를 쓰거나 읽을 때 사용하는 구조체이다
typedef struct _MEMORY_CHUNKS
{
 PVOID pVirtualAddress;
 PVOID pBuffer;
 DWORD dwBufferSize;
} MEMORY_CHUNKS, *PMEMORY_CHUNKS;
//ZwSystemDebugControl의 첫 번째 인자
typedef enum _SYSDBG_COMMAND
{
 SysDbgCopyMemoryChunks_0 = 0x08,  //가상 메모리로부터 데이터를 읽을 때
  SysDbgCopyMemoryChunks_1 = 0x09,  //가상 메모리에 데이터를 쓸 때
} SYSDBG_COMMAND;
//DLL로 부터 로드해 사용해야 한다.. windows.h에 정의되어있지 않다
typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION ) ( IN SYSTEM_INFORMATION_CLASS
                SystemInformationClass,
                IN OUT PVOID SystemInformation,
                IN ULONG SystemInformationLength,
                OUT PULONG ReturnLength OPTIONAL );
typedef NTSTATUS ( __stdcall *ZWSYSTEMDEBUGCONTROL ) ( IN SYSDBG_COMMAND SysDbgChunks,
               IN OUT PMEMORY_CHUNKS pQueryBuff,
               DWORD dwSize, DWORD, DWORD, NTSTATUS *pResult);
//***********************************************************//
// ZwQuerySystemInformation은 시스템 정보를 얻어오는 함수로, //
// 첫 번째 인자에 16을 넘길 경우 현재 로드 되어있는 모든     //
// 핸들의 정보를 얻어오도록 되어있다.                        //
//***********************************************************//
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
//***********************************************************//
// ZwSystemDebugControl은 시스템 디버그에 관련된 명령을 수행 //
// 하는 함수로, 8또는 9를 넘길 경우 가상 메모리 공간을       //
// 읽거나 쓴다.                                              //
//***********************************************************//
ZWSYSTEMDEBUGCONTROL  ZwSystemDebugControl;
BOOL EnablePrivilege(LPCSTR lpName, HANDLE hProcess);       //알맞는 권한을 획득한다
BOOL GetNativeAPIAddress();              //Native API의 주소를 얻어온다
PSYSTEM_HANDLE_INFORMATION GetProcessSystemHandleInfo(ULONG ulProcessId);  //주어진 프로세스의 시스템 핸들 정보를 얻어온다
BOOL ReadVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize);  //가상 메모리 공간을 읽는다
BOOL WriteVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize);  //가상 메모리 공간에 데이터를 쓴다
BOOL HideProcess(DWORD dwProcessId);           //프로세스를 숨긴다
BOOL EnablePrivilege(LPCSTR lpName, HANDLE hProcess)
{
 //권한 토큰 구조체
 TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };
 //lpName으로 지정된 권한 이름에 대한 LUID를 얻어낸다
 LookupPrivilegeValue(0, lpName, &priv.Privileges[0].Luid);
 
 //프로세스의 토큰 핸들을 얻고
 HANDLE hToken;
 OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
 
 //입력받은 권한으로 프로세스 권한을 바꾼다
 AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof(TOKEN_PRIVILEGES), 0, 0);
 
 BOOL rv = GetLastError() == ERROR_SUCCESS;
 
 CloseHandle(hToken);
 return rv;
}
//Native API의 주소를 얻어온다
BOOL GetNativeAPIAddress()
{
 //ntdll.dll로드
 HMODULE hNTDll;
 
 if( (hNTDll = GetModuleHandle("ntdll.dll")) == NULL )
  if( (hNTDll = LoadLibrary("ntdll.dll")) == NULL )
   return FALSE;
  
  //ZwQuerySystemInformation로드
  if( (ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(
   hNTDll, "ZwQuerySystemInformation")) == NULL )
   return FALSE;
  
  //ZwSystemDebugControl로드
  if( (ZwSystemDebugControl = (ZWSYSTEMDEBUGCONTROL)GetProcAddress(
   hNTDll, "ZwSystemDebugControl")) == NULL )
   return FALSE;
  
  return TRUE;
}
//프로세스의 아이디로 부터 ActiveProcessLinks정보를 가진 EPROCESS구조체의
//가상 메모리 공간상의 주소를 얻어온다
PSYSTEM_HANDLE_INFORMATION GetProcessSystemHandleInfo(ULONG ulProcessId)
{
 NTSTATUS result;
 PVOID pBuffer = NULL;        //데이터를 읽어올 배열
 PSYSTEM_HANDLE_INFORMATION pSystemHandleInfo;  //핸들 정보 배열
 PSYSTEM_HANDLE_INFORMATION pProcessHandle = NULL; //리턴할 값
 
 //핸들의 수를 모르기 때문에, 적당한 사이즈를 알 수 없다
 //때문에 반복문을 돌면서 그 값을 찾아야 한다
 for( ULONG ulSize=1; ; ulSize *= 2 )
 {
  //정한 사이즈로 메모리를 할당한다
  if( (pBuffer = malloc(ulSize) ) == NULL )
   //실패할 경우 NULL 리턴
   return NULL;
  
  //시스템에 로드된 모든 핸들의 정보를 조사한다
  result = ZwQuerySystemInformation(SystemHandleInformation, pBuffer, ulSize, NULL);
  
  //실패할 경우
  if( !NT_SUCCESS(result) )
  {
   //메모리 해제
   free(pBuffer);
   //사이즈를 잘못 정했다면 반복문을 계속 수행한다
   if( result == STATUS_INFO_LENGTH_MISMATCH )
   {
    pBuffer = NULL;
   }
   //사이즈를 제대로 정했는데 실패한 것이라면 NULL을 리턴
   else
   {
    return NULL;
   }
  }
  //성공한 경우
  else
   //반복문을 빠져나간다
   break;
 }
 
 //읽어온 데이터의 첫 번째 4바이트는 배열의 길이 정보이다
 ULONG ulNumberOfHandles = *(PULONG)pBuffer;
 //다음 4바이트 부터는 SYSTEM_HANDLE_INFORMATION구조체의 배열이다
 pSystemHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((PBYTE)pBuffer + sizeof(ULONG));
 
 //핸들의 수 만큼 반복문을 돌면서
 for( ULONG i=0; i<ulNumberOfHandles; i++ )
 {
  //입력받은 프로세스의 아이디와 일치하는 프로세스 아이디를 가지는
  //프로세스 핸들을 찾을 경우
  // (SYSTEM_HANDLE_INFORMATION구조체의 ObjectTypeNumber는
  // 오브젝트의 종류를 나타내는 것으로, 5번은 프로세스를 뜻한다)
  if( pSystemHandleInfo[i].ProcessId == ulProcessId &&
   pSystemHandleInfo[i].ObjectTypeNumber == 5 )
  {
   //리턴할 값으로 저장하고 반복문을 빠져나간다
   pProcessHandle = new SYSTEM_HANDLE_INFORMATION;
   memcpy(pProcessHandle, pSystemHandleInfo + i, sizeof(SYSTEM_HANDLE_INFORMATION));
   break;
  }
 }
 
 //메모리 해제
 if( pBuffer )
  free(pBuffer);
 
 //찾아낸 값을 리턴
 return pProcessHandle;
}
//가상 메모리 공간을 읽어온다
BOOL ReadVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize)
{
 NTSTATUS result;
 
 //메모리 청크 구조체
 MEMORY_CHUNKS QueryBuff;
 QueryBuff.pVirtualAddress = pAddress; //가상 메모리 주소
 QueryBuff.pBuffer = pBuffer;   //버퍼의 주소
 QueryBuff.dwBufferSize = dwBufferSize; //버퍼의 크기
 
 //가상 메모리 공간을 읽어서 버퍼에 기록한다
 ZwSystemDebugControl(SysDbgCopyMemoryChunks_0, &QueryBuff,
  sizeof(MEMORY_CHUNKS), NULL, 0, &result);
 
 return NT_SUCCESS(result);
}
//가상 메모리 공간에 데이터를 쓴다
BOOL WriteVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize)
{
 NTSTATUS result;
 
 //메모리 청크 구조체
 MEMORY_CHUNKS QueryBuff;
 QueryBuff.pVirtualAddress = pAddress; //가상 메모리 주소
 QueryBuff.pBuffer = pBuffer;   //버퍼의 주소
 QueryBuff.dwBufferSize = dwBufferSize; //버퍼의 크기
 
 //버퍼로 부터 값을 읽어서 가상 메모리 공간에 기록한다
 ZwSystemDebugControl(SysDbgCopyMemoryChunks_1, &QueryBuff,
  sizeof(MEMORY_CHUNKS), NULL, 0, &result);
 
 return NT_SUCCESS(result);
}
//프로세스를 감춘다
BOOL HideProcess(DWORD dwProcessId)
{
 //OS의 버젼에 따라 EPROCESS내의 ActiveProcessLinks의 오프셋이 다르기 때문에
 //OS의 버젼을 파악하고 그에 따라 오프셋을 맞추어야 한다
 
 OSVERSIONINFO osvi;
 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 //OS의 버젼을 얻어온다
 GetVersionEx(&osvi);
 
 int nFOffset, nBOffset;
 if( osvi.dwMajorVersion == 5 )
 {
  switch( osvi.dwMinorVersion )
  {
  case 0: //Win2K
   nFOffset = 0xa0;
   nBOffset = 0xa4;
   break;
   
  case 1: //WinXP
   nFOffset = 0x88;
   nBOffset = 0x8C;
   break;
   
  case 2: //Win2003
   nFOffset = 0x8a;
   nBOffset = 0x8e;
   break;
   
  default:
   return FALSE;
  }
 }
 else if( osvi.dwMajorVersion == 4 &&
  osvi.dwMinorVersion == 0 &&
  osvi.dwPlatformId == 2 ) //WinNT
 {
  nFOffset = 0x98;
  nBOffset = 0x9c;
 }
 else
  return FALSE;
 
 //프로세스를 열어야만 프로세스 핸들이 시스템에 로드된다
 //프로세스를 연다
 OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwProcessId);
 //주어진 프로세스의 시스템 핸들 정보를 얻어온다
 PSYSTEM_HANDLE_INFORMATION pProcessHandle = GetProcessSystemHandleInfo(dwProcessId);
 
 //잘못된 값을 얻어온 경우 리턴
 if( pProcessHandle == NULL )
  return FALSE;
 
 //EPORCESS의 가상 메모리 공간상의 주소를 얻어온다
 PVOID pEProcess = pProcessHandle->Object;
 
 delete pProcessHandle;
 
 //프로세스 핸들을 얻어온다 - 디버그 권한 설정에 사용된다
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId());
 
 //디버그 권한을 설정한다
 if( EnablePrivilege(SE_DEBUG_NAME, hProcess) == FALSE )
  return FALSE;
 
 CloseHandle(hProcess);
 
 
 PVOID pFlink;
 PVOID pBlink;
 
 //ActiveProcessLinks의 Flink와 Blink의 가상 메모리 공간상의 주소를 얻어온다
 if( ReadVirtualMemory((BYTE *)pEProcess + nFOffset, &pFlink, sizeof(PVOID)) )
  if( ReadVirtualMemory((BYTE *)pEProcess + nBOffset, &pBlink, sizeof(PVOID)) )
   //Flink의 Blink에 Blink를, Blink의 Flink에 Flink를 기록하여,
   //프로세스를 리스트에서 제거한다
   if( WriteVirtualMemory((BYTE *)pFlink + sizeof(PLIST_ENTRY), &pBlink, sizeof(PVOID)) )
    if( WriteVirtualMemory((BYTE *)pBlink, &pFlink, sizeof(PVOID)) )
     return TRUE;
    
    return FALSE;
}
 
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 // TODO: Place code here.
 GetNativeAPIAddress();
 HideProcess(GetCurrentProcessId());
 
 while(1) {
  ::MessageBox(NULL,"test", "test", MB_OK);
  Sleep(1000);
 }
 
 return 0;
}
 

일반적으로 유저모드에서 커널메모리 접근은 차단되어있다.
단, 예외적으로 XP에서 관리자 권한을 가지고있고 SE_DEBUG_NAME 특근을 얻을 수 있으면
ntdll.dll 의 ZwSystemDebugControl Native API 함수를 이용하요 커널메모리에 접근이 가능하다.


 KernelMemory.h
#pragma once

//NTSTATUS값이 0이상이면 보통 성공한 상태를 의미한다
#define NT_SUCCESS(Status)    ((NTSTATUS)(Status) >= 0)
typedef LONG       NTSTATUS;

typedef struct _MEMORY_CHUNKS
{
 PVOID pVirtualAddress;
 PVOID pBuffer;
 DWORD dwBufferSize;
} MEMORY_CHUNKS, *PMEMORY_CHUNKS;

typedef enum _SYSDBG_COMMAND
{
 SysDbgCopyMemoryChunks_0 = 0x08,  //가상 메모리로부터 데이터를 읽을 때
 SysDbgCopyMemoryChunks_1 = 0x09,  //가상 메모리에 데이터를 쓸 때
} SYSDBG_COMMAND;
 
typedef NTSTATUS ( __stdcall *ZWSYSTEMDEBUGCONTROL ) ( IN SYSDBG_COMMAND SysDbgChunks,
               IN OUT PMEMORY_CHUNKS pQueryBuff,
               DWORD dwSize, DWORD, DWORD, NTSTATUS *pResult);

class CKernelMemory
{

 ZWSYSTEMDEBUGCONTROL  m_ZwSystemDebugControl;
public:
 CKernelMemory(void);
 ~CKernelMemory(void);
 BOOL Init(HANDLE hProcess);
 BOOL ReadVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize);
 BOOL WriteVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize);
protected:
 BOOL EnablePrivilege(LPCSTR lpName, HANDLE hProcess);
 BOOL GetNativeAPIAddress();

};

 


KenelMemory.cpp
#include "stdafx.h"
#include "KernelMemory.h"
CKernelMemory::CKernelMemory(void)
{
 
 m_ZwSystemDebugControl = NULL;
}
CKernelMemory::~CKernelMemory(void)
{
}
BOOL CKernelMemory::Init(HANDLE hProcess)
{
 if (!EnablePrivilege(SE_DEBUG_NAME, hProcess))
 {  
  return FALSE;
 }
 return GetNativeAPIAddress();
}
 
//Native API의 주소를 얻어온다
BOOL CKernelMemory::GetNativeAPIAddress()
{
 //ntdll.dll로드
 HMODULE hNTDll;
 if( (hNTDll = GetModuleHandle("ntdll.dll")) == NULL )
 {  
  if( (hNTDll = LoadLibrary("ntdll.dll")) == NULL )
  {   
   return FALSE;
  }
 }
 //ZwSystemDebugControl로드
 if( (m_ZwSystemDebugControl = (ZWSYSTEMDEBUGCONTROL)GetProcAddress(
  hNTDll, "ZwSystemDebugControl")) == NULL )
 {  
  return FALSE;
 } 
 return TRUE;
}
 

//가상 메모리 공간을 읽어온다
BOOL CKernelMemory::ReadVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize)
{
 NTSTATUS result;
 //메모리 청크 구조체
 MEMORY_CHUNKS QueryBuff;
 QueryBuff.pVirtualAddress = pAddress; //가상 메모리 주소
 QueryBuff.pBuffer = pBuffer;   //버퍼의 주소
 QueryBuff.dwBufferSize = dwBufferSize; //버퍼의 크기
 //가상 메모리 공간을 읽어서 버퍼에 기록한다
 m_ZwSystemDebugControl(SysDbgCopyMemoryChunks_0, &QueryBuff,
  sizeof(MEMORY_CHUNKS), NULL, 0, &result);
 return NT_SUCCESS(result);
}
//가상 메모리 공간에 데이터를 쓴다
BOOL CKernelMemory::WriteVirtualMemory(PVOID pAddress, PVOID pBuffer, DWORD dwBufferSize)
{
 NTSTATUS result;
 //메모리 청크 구조체
 MEMORY_CHUNKS QueryBuff;
 QueryBuff.pVirtualAddress = pAddress; //가상 메모리 주소
 QueryBuff.pBuffer = pBuffer;   //버퍼의 주소
 QueryBuff.dwBufferSize = dwBufferSize; //버퍼의 크기
 //버퍼로 부터 값을 읽어서 가상 메모리 공간에 기록한다
 m_ZwSystemDebugControl(SysDbgCopyMemoryChunks_1, &QueryBuff,
  sizeof(MEMORY_CHUNKS), NULL, 0, &result);
 return NT_SUCCESS(result);
}
 
BOOL CKernelMemory::EnablePrivilege(LPCSTR lpName, HANDLE hProcess)
{
 //권한 토큰 구조체
 TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };
 //lpName으로 지정된 권한 이름에 대한 LUID를 얻어낸다
 LookupPrivilegeValue(0, lpName, &priv.Privileges[0].Luid);
 //프로세스의 토큰 핸들을 얻고
 HANDLE hToken;
 OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
 //입력받은 권한으로 프로세스 권한을 바꾼다
 AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof(TOKEN_PRIVILEGES), 0, 0);
 BOOL rv = GetLastError() == ERROR_SUCCESS;
 CloseHandle(hToken);
 return rv;
}



GetPixel 함수 대체 (GetPixel Alternative)

프로그래밍 2011. 6. 22. 11:56 Posted by friday13th



GetDC는 가능하나 GetPixel 함수를 쓸수었을때 DC의 DDB를 DIB로 바꾸어 픽셀 색상 정보를 가져옴.
MyGetPixel 사용


DIB.h

#pragma once
 
HANDLE DDBToDIB(CBitmap &bitmap, DWORD dwCompression, CPalette *pPal);
BOOL WriteDIB(LPTSTR szFileName, HANDLE hDIB);
HANDLE OpenDIB(HWND hWNd, RECT &rtRect );
COLORREF GetDIBPixel(HANDLE hDIB, int x, int y);
void CloseDIB(HANDLE hDIB);
COLORREF MyGetPixel(HWND hWnd, int x, int y);


DIB.cpp

#include "stdafx.h"
#include "DIB.h"
HANDLE DDBToDIB(CBitmap &bitmap, DWORD dwCompression, CPalette *pPal)
{
 BITMAP       bm;
 BITMAPINFOHEADER bi;
 LPBITMAPINFOHEADER  lpbi;
 DWORD       dwLen;
 HANDLE       hDIB;
 HANDLE        handle;
 HDC        hDC;
 HPALETTE      hPal;

 // Return Value : A HANDLE to the attached Windows GDI object
 ASSERT( bitmap.GetSafeHandle() );
 // The function has no arg for bitfields
 if( dwCompression == BI_BITFIELDS )
  return NULL;
 // If a palette has not been supplied use defaul palette
 hPal = (HPALETTE) pPal->GetSafeHandle();
 if (hPal==NULL)
  hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
 // Get bitmap information
 bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
 // Initialize the bitmapinfoheader ( Bitmap Information )
 bi.biSize      = sizeof(BITMAPINFOHEADER);             // 비트맵 헤더크기
 bi.biWidth      = bm.bmWidth;                           // 비트맵의 가로 크기
 bi.biHeight   = bm.bmHeight;                          // 비트맵의 세로 크기
 bi.biPlanes   = 1;                                    // Plane 수 (1로 설정)
 bi.biBitCount  = bm.bmPlanes * bm.bmBitsPixel;         // 한 픽셀당 비트수
 bi.biCompression = dwCompression;                        // 압축 유무
 bi.biSizeImage  = 0;                                    // 그림 데이터 크기
 bi.biXPelsPerMeter = 0;                                    // 한 픽셀당 가로 미터
 bi.biYPelsPerMeter = 0;                                    // 한 픽셀당 세로 미터
 bi.biClrUsed  = 0;                                    // 그림에서 실제 사용되는 컬러수
 bi.biClrImportant = 0;                                    // 중요하게 사용되는 컬러
 // Compute the size of the  infoheader and the color table
 int nColors = (1 << bi.biBitCount);
 if( nColors > 256 )
  nColors = 0;
 dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);
 // We need a device context to get the DIB from
 hDC = ::GetDC(NULL);
 hPal = SelectPalette(hDC,hPal,FALSE);
 RealizePalette(hDC);
 // Allocate enough memory to hold bitmapinfoheader and color table
 hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
 if (!hDIB){
  SelectPalette(hDC,hPal,FALSE);
  ::ReleaseDC(NULL,hDC);
  return NULL;
 }
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 *lpbi = bi;
 // Call GetDIBits with a NULL lpBits param, so the device driver
 // will calculate the biSizeImage field
 GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
  (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
 bi = *lpbi;
 // If the driver did not fill in the biSizeImage field, then compute it
 // Each scan line of the image is aligned on a DWORD (32bit) boundary
 if (bi.biSizeImage == 0){
  bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
   * bi.biHeight;
  // If a compression scheme is used the result may infact be larger
  // Increase the size to account for this.
  if (dwCompression != BI_RGB)
   bi.biSizeImage = (bi.biSizeImage * 3) / 2;
 }
 // Realloc the buffer so that it can hold all the bits
 dwLen += bi.biSizeImage;
 if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
  hDIB = handle;
 else{
  GlobalFree(hDIB);
  // Reselect the original palette
  SelectPalette(hDC,hPal,FALSE);
  ::ReleaseDC(NULL,hDC);
  return NULL;
 }
 // Get the bitmap bits
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 // FINALLY get the DIB
 BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
  0L,    // Start scan line
  (DWORD)bi.biHeight,  // # of scan lines
  (LPBYTE)lpbi    // address for bitmap bits
  + (bi.biSize + nColors * sizeof(RGBQUAD)),
  (LPBITMAPINFO)lpbi,  // address of bitmapinfo
  (DWORD)DIB_RGB_COLORS);  // Use RGB for color table
 if( !bGotBits )
 {
  GlobalFree(hDIB);
  SelectPalette(hDC,hPal,FALSE);
  ::ReleaseDC(NULL,hDC);
  return NULL;
 }
 SelectPalette(hDC,hPal,FALSE);
 ::ReleaseDC(NULL,hDC);
 return hDIB;
}
BOOL WriteDIB(LPTSTR szFileName, HANDLE hDIB)
{
 BITMAPFILEHEADER      hdr;
 LPBITMAPINFOHEADER    lpbi;
 if (!hDIB)
  return FALSE;
 CFile file;
 if (!file.Open(szFileName, CFile::modeWrite | CFile::modeCreate))
  return FALSE;
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 // 한 픽셀당 비트수를 왼쪽으로 1 이동 (shift)
 int nColors = 1 << lpbi->biBitCount;
 // Fill in the fields of the file header ( Bitmap file header )
 hdr.bfType        = ((WORD) ('M' << 8) | 'B');         // is always "BM"  
 hdr.bfSize        = GlobalSize (hDIB) + sizeof(hdr);   // 비트맵 파일의 전체 크기
 hdr.bfReserved1   = 0;                                 // 예약변수 (0으로 설정)
 hdr.bfReserved2   = 0;                                 // 예약변수 (0으로 설정)
 // 파일에서 비트맵 데이터가 있는 위치
 hdr.bfOffBits     = (DWORD)(sizeof(hdr) + lpbi->biSize + nColors * sizeof(RGBQUAD)); 
 // Write the file header
 file.Write(&hdr, sizeof(hdr));
 // Write the DIB header and the bits
 file.Write(lpbi, GlobalSize(hDIB));
 file.Close();
 return TRUE;
}

HANDLE OpenDIB(HWND hWNd, RECT &rtRect)
{
 if (hWNd==NULL)
  return NULL;
 HDC hDC = GetDC(hWNd);
 CDC dc;
 dc.Attach(hDC);
 CDC *pDC = &dc;
 CRect Rect = rtRect;
 CBitmap bitmap;
 CDC MemDC;
 MemDC.CreateCompatibleDC(pDC);
 bitmap.CreateCompatibleBitmap(pDC, Rect.Width(),Rect.Height());
 CBitmap *pOldBitmap = MemDC.SelectObject(&bitmap);
 MemDC.BitBlt(0,0 , Rect.Width(),Rect.Height(), pDC, Rect.left, Rect.top, SRCCOPY);
 CPalette m_Pal;
 HANDLE hDIB = DDBToDIB(bitmap, BI_RGB, &m_Pal);
 //  if (hDIB == NULL) {
 //   // AfxMessageBox("bitmap을 DIB으로 convert할 수 없습니다.", MB_ICONSTOP);
 //   return 0 ;
 //  }
 return hDIB;

}
COLORREF GetDIBPixel(HANDLE hDIB, int x, int y)
{
 LPBITMAPINFOHEADER    lpbi;
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 BYTE *pBit = ((BYTE*)hDIB )+ sizeof(BITMAPINFOHEADER) + 4;
 int pitch  = ( (((lpbi->biWidth*lpbi->biBitCount)+31)/32)*4 );
 BYTE* pPixel = (BYTE*) ( LPBYTE( pBit )+( (lpbi->biHeight-y-1) *pitch)+(( (x) *lpbi->biBitCount)/8) );
 COLORREF color=RGB(pPixel[2], pPixel[1], pPixel[0]);
 return color;
}
void CloseDIB(HANDLE hDIB)
{
 if (hDIB)
  GlobalFree(hDIB);
}

COLORREF MyGetPixel(HWND hWnd, int x, int y)
{
 CRect rt(x,y,x+1,y+1); 
 HANDLE hDIB = OpenDIB(hWnd, rt);
 if (hDIB==NULL)
  return 0;
 COLORREF retColor = GetDIBPixel(hDIB, 0, 0);
 CloseDIB(hDIB);
 return retColor;
}