728x90

APC (Asynchronous Pprocedure Call) 을 사용할 때 개발자가 사용할 수 있는 함수이다.

 

참조 자료

https://repnz.github.io/posts/apc/user-apc/

 

APC Series: User APC API · Low Level Pleasure

APC Series: User APC API Sun, May 17, 2020 Hey! Long time no see. Coronavirus makes it harder for me to write posts, I hope I’ll have the time to write - I have a lot I want to share! One of the things I did in the last few weeks is to explore the APC me

repnz.github.io

 

https://repnz.github.io/posts/apc/kernel-user-apc-api/

 

APC Series: User APC Internals · Low Level Pleasure

APC Series: User APC Internals Wed, Jun 3, 2020 Hey! This is the second part of the APC Series, If you haven’t read it I recommend you to read the first post about User APC API. where I explore the internals of APC objects in Windows. In this part I’ll

repnz.github.io

 

https://repnz.github.io/posts/apc/wow64-user-apc/

 

APC Series: KiUserApcDispatcher and Wow64 · Low Level Pleasure

APC Series: KiUserApcDispatcher and Wow64 Sun, Jun 28, 2020 I recommend to read the previous posts before reading this one: Let’s continue our discussion about APC internals in windows: This time we’ll discuss APC dispatching in user mode and how APC w

repnz.github.io

 

https://sevrosecurity.com/2020/04/08/process-injection-part-1-createremotethread/

 

Process Injection Part 1 | CreateRemoteThread() | Sevro Security

Process Injection using Direct Syscalls and CreateRemoteThread

sevrosecurity.com

 

https://sevrosecurity.com/2020/04/13/process-injection-part-2-queueuserapc/

 

Process Injection Part 2 | QueueUserAPC() | Sevro Security

Low Level Process Injection using QueueUserAPC() via direct x86 asm syscalls to bypass AV, EDR, and Sysmon.

sevrosecurity.com

 

728x90
728x90

프로그램이 에러로 인해 죽는다거나 했을 때 감지하는 방법이 없을까하고 찾다보니 

c++의 signal을 이용하면 가능한 것을 확인했다.

 

#include <iostream>
#include <csignal>
#include <thread>

using namespace std;
using namespace std::literals::chrono_literals;

void signalHandler(int signum)
{
    cout << "interrupt signal (" << signum << ") received. \n";
}

int main()
{
    signal(SIGSEGV, signalHandler); // segment violation
    
    while(1)
    {
        cout << "sleep..." << endl;
        std::this_thread::sleep_for(1ms);
        
        static int count = 0;
        ++count;
        
        if (count > 100)
        {
            struct n
            {
                int a;
            }
            
            n* nn = nullptr;
            printf("int a : %d \n", nn->a); // nullptr 참조 후 프로그램 죽음.
        }
    }
}

 

결과

 

ref : http://seorenn.blogspot.com/2011/02/sigsegv.html

728x90
728x90

Memory Leak을 Detect하는 코드를 사용할 때 아래와 같이 new를 새롭게 define해서 사용한다.

   1 #ifdef _DEBUG
   2 #define new new( _CLIENT_BLOCK, __FILE__, __LINE__ )
   3 #endif

 

개발을 하다보면 이 코드가 문제가 될때가 있다. 예를 들면 다른 OpenSource를 사용할때...

그럴때에는 그 헤더를 사용할 때에는 push_macro()를 이용해서 문제를 해결할 수 있다.

#pragma push_macro("new")
#undef new

#include "OpenSource.h" // 오픈소스 헤더

#pragma pop_macro("new")

 

자세한 내용은 아래의 글을 참조하자.

https://dataonair.or.kr/db-tech-reference/d-lounge/technical-data/?mod=document&uid=235804

 

C++ 프로그래밍 : 알면 유용한 메모리 연산자

C++ 프로그래밍 알면 유용한 메모리 연산자 C/C++는 메모리를 직접 다룰 수 있어 개발자 사이에서도 호불호가 극명하게 갈리는 편이다. 메모리를 직접 제어해야 하는 어려움은 다른 언어에도 많은

dataonair.or.kr

 

728x90
728x90

 

기본적으로는 MD로 되기 때문에 vcpkg\scripts\buildsystems\msbuild\vcpkg.targets에서

<VcpkgOSTarget>windows</VcpkgOSTarget> == MD

<VcpkgOSTarget>windows-static</VcpkgOSTarget> == MT

 

 

728x90
728x90
#include <iostream>
#include <memory> 
#include <windows.h>
#include <winuser.h>

bool IsScreenLocked()
{
	HDESK desktopHandle = OpenInputDesktop(0, false, DESKTOP_SWITCHDESKTOP);
	if (desktopHandle == 0)
	{
		desktopHandle = OpenDesktopA("Default", 0, false, DESKTOP_SWITCHDESKTOP);
	}
	if (desktopHandle != 0)
	{
		if (SwitchDesktop(desktopHandle))
		{
			CloseDesktop(desktopHandle);
		}
		else
		{
			CloseDesktop(desktopHandle);
			return true;
		}
	} return false;
}

bool IsScreenSaverRunning()
{
	int isRunning = 0;
	if (!SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &isRunning, 0))
	{
		return false;
	}
	if (isRunning)
	{
		return true;
	}
	return false;
}

int main()
{
	while (true)
	{
		if (IsScreenLocked())
		{
			printf("LockScreen : true");
		}
		else
		{
			printf("LockScreen : false");
		}

		if (IsScreenSaverRunning())
		{
			printf("ScreenSaver : true");
		}
		else
		{
			printf("ScreenSaver : false");
		}

		Sleep(100);
	}
}

 

참조 : https://icodebroker.tistory.com/9207

728x90
728x90

Framework에서 기본적인 Sleep()을 주다보니 정확하지 않은 시간동안 잠들었다가 깨어나기 때문에 발생하는 frame loss라던가 정확한 latency 측정이 되지 않아서 정확하게 지정된 시간동안 잠들었다가 깨어나는 Sleep()을 찾게되었다.

 

동작에 대해 간단히 설명하면 Sleep(16)을 원한다면 Sleep(15)를 하고 남은 1ms은 while()을 돌면서 대기하는 방식이다.

 

참고 : https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/

 

Making an accurate Sleep() function | computerBear

There are many cases in programming where I wish the system Sleep() function was more accurate. Real-time rendering immediately comes to mind, as do animated GUI’s. In both of these cases you want some piece of code to run on a fixed timer, executing pre

blat-blatnik.github.io

 

728x90
728x90

이번에 개발한 프로그램이 서비스로 동작해야되는 상황이와서 검색하다보니 이미 잘 구현해놓은게 있어서 갖다쓰니 되었다.

1.예제로 쓸 프로그램을 준비한다.즉 서비스로 돌릴 프로그램이 있어야한다.

-멀티쓰레드기반의 파일 전송서버를 예로 들겠다.

 

2.서비스클래스를 원래의 프로그램에 추가한다.

서비스 모듈인 Service.cpp와 Servie.h라는 파일을 추가한다.

 

3.코딩은 생각보다 아주 간단하다.

/*

원프로그램 제작자
(Author :- Nish [BusterBoy] EMail :- nishinapp@yahoo.com)

 

서비스프로그램화 : 자작
*/

#include "stdafx.h"

#include "MTServer.h"
#include <tchar.h>
#include "Service.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CWinApp theApp;
SOCKET server;

using namespace std;

UINT  MTServerThread(LPVOID pParam);
UINT  ClientThread(LPVOID pParam);
BOOL ParseCmd(char *str, CString& cmd, CString& params);
BOOL SendFile(SOCKET s, CString fname);


class CUpdateService: public CService
{
public:
 VOID Main(void) 
 {
  CService::Begin(_T("UpdateServer"));//내부에서 OnStarted호출
  CService::End(); //내부에서 OnStopped호출
 }
protected:
 void OnStarted()//서비스 시작시 동작할 쓰레드나 타이머
 {
  AfxBeginThread(MTServerThread,0);
  
 }
 void OnStopped()//서비스가 멈추었을 때 해제코드
 {
  closesocket(server);
  WSACleanup();
 }

};


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{

//원 소스에서 주석처리한 부분
 /*int nRetCode = 0; 

 cout << "Press ESCAPE to terminate program\r\n";
 AfxBeginThread(MTServerThread,0);
 while(_getch()!=27);

 closesocket(server);
 WSACleanup();

 return nRetCode;*/

 

 CUpdateService upServ;
 if(argc == 2)
 {
  if(_tcscmp(argv[1],_T("-i")) == 0)//서비스 설치
  {
   upServ.Install(_T("UpdateServer"));
  }
  else if(_tcscmp(argv[1],_T("-u")) == 0) //서비스 제거
  {
   upServ.Uninstall(_T("UpdateServer"));
  }
  return TRUE;
 }

 upServ.Main();

 return TRUE;
 
}


UINT  MTServerThread(LPVOID pParam)
{

.....중략 //파일을 다운받아서 보자.서비스와 관련하여 그렇게 중요한 내용이 없다.  
}

 

4.서비스 프로그램 설치

 

(1)빌드를 하면 실행파일이 만들어지는데,위의 예제에서는 서비스이름이 UpdateServer니까

폴더도 UpdateServer로 만들고 거기에다가 실행파일을 두자.

만약에 환경설정파일(INI파일,이미지등등이 필요하다면 여기에 다 담아야한다.)

그리고 이 폴더 내에는 텍스트파일을 열어 확장자만 바꾼 install.bat과 uninstall.bat을 준비한다.

 

위 프로젝트의 실행파일은 MTServer로 되어 있다.(물론 프로젝트 설정으로 바꿀 수 있다.)

install.bat이라는 파일은 MTServer.exe -i 라고 적고(설치배치파일)

uninstall.bat에는 MTServer -u 라고 적는다.(제거배치파일)

 

(2)이렇게 만들어진 UpdateServer폴더를 Windows 혹은 WINNT 아래에 있는 System32폴더에 복사해 넣자.

주의:다른 폴더에 두어도 상관없지만,다른 폴더에 두는 경우에 환경설정파일이나 이미지파일은 절대경로로 설정하는 것이 좋다.

본인이 경험한 결과 서비스프로그램의 상대경로의 시작지점이 System32이라는 것을 알게되었다. 

 

(3)이제 install.bat을 누르면 서비스가 등록된다.

(4)시작을 하려면 제어판 -관리도구 -서비스 로 들어가면 반갑게 UpdateServer라는 서비스가 만들어져 있을 것이다.

(5)서비스를 시작한다.제대로 프로그레스바가 진행되고 시작하면 제대로 된 것이다.

 

5.테스트

(1)텔넷으로 서버에 접속해보자.

실행에서 다음과 같이 입력하고 엔터클릭

telnet 127.0.0.1 20248

 

(2)서버접속 메시지 수신으로 서비스가 정상적으로 동작한다는 것을 알 수 있다.

 

ServiceSample.zip
0.02MB

 

참조 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=bmk5133&logNo=80090120069

 

C++ 서비스 프로그램 제작

1.예제로 쓸 프로그램을 준비한다.즉 서비스로 돌릴 프로그램이 있어야한다. -멀티쓰레드기반의 파일 전송...

blog.naver.com

 

728x90
728x90

이건 대학생때 정보보호학과 수업에서 과제로 했던건데... 살다보니 쓸일이 생기네 ㄷㄷ

 

아래 코드에서

s.seed는 난수생성을 위한 seed 값

s.length는 생성할 난수의 갯수

X, Y, Z는 마음대로 지정하면 되는 값이다.

 

이 함수를 이용한다면 난수가 균등하게 0~255의 값 사이로 만들어진다.

동일한 seed 를 사용한다면 동일한 난수가 생성이 된다.

물론 seed와 x,y,z를 time을 이용하여 마음대로 넣는다면... 예측이 불가능한 값이 될 것이다.

 

728x90

+ Recent posts