23

[原创]flv 抓取小工具

dummy 2007-10-20 22:53 12451
// 以前就想写个这样的工具,一直都很懒。
// 今天实在无聊,才踏踏实实写出
// 主要功能就是在抓取 flv 的路径, 实现方法就是 patch fash 控件处理 flv 路径的地方。
// 只在 xp 下测试了 flash9d.ocx

/*
提供 flv 路径捕获接口
written by dummyz@126.com
 2007/10/20
*/
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <windows.h>
#include <TlHelp32.h>
#include "GetFlv.h"
#include "Hook.h"

//////////////////////////////////////////////////////////////////////////
// 类型定义
//////////////////////////////////////////////////////////////////////////
typedef HMODULE (WINAPI* PFN_LoadLibraryExW)(LPCWSTR,HANDLE,DWORD);



//////////////////////////////////////////////////////////////////////////
// 全局变量
//////////////////////////////////////////////////////////////////////////
#pragma data_seg(".sh")
HHOOK __hMouseHook = NULL;
HWND __hWnd = NULL;
int __nMonitorState = 0;
#pragma data_seg()
#pragma comment(linker, "/section:.sh,rws")

HMODULE __hModule;
HOOKIMPORT __HookImpStc[2];

struct
{
	ULONG sub_300BE976; // 300BE976
	ULONG PatchedCode; // 300910DB
	BOOL bPatched;
} __PatchFlashOcx;

//////////////////////////////////////////////////////////////////////////
// 函数实现
//////////////////////////////////////////////////////////////////////////


void __stdcall LogOut(PCTSTR pszString)
{
	if ( pszString != NULL )
	{
		PCTSTR p = strrchr(pszString, '.');
		if ( p != NULL && stricmp(p, ".flv") == 0 )
		{
#if 0
			FILE* f = fopen("c:\\getflv.log", "a+");
			if ( f != NULL )
			{
				fprintf(f, "%s\n", pszString);
				fclose(f);
			}
#else
			COPYDATASTRUCT cds;
			
			cds.dwData = 0x8702;
			cds.cbData = strlen(pszString) + 1;
			cds.lpData = (LPVOID)pszString;
			SendMessage(__hWnd, WM_COPYDATA, 0, (LPARAM)&cds);
#endif
		}
	}
}

int __declspec(naked) Dummy_Sub300BE976()
{
	__asm
	{
		mov		eax, [esp + 8]
		push	ecx
		push	eax
		call	LogOut
		pop		ecx
		jmp		[__PatchFlashOcx].sub_300BE976
	}
}

BOOL PatchFlashOcx(LPVOID lpBaseAddr)
{
	__try
	{
		// search code
		PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)lpBaseAddr;
		PIMAGE_NT_HEADERS pNtH = (PIMAGE_NT_HEADERS)((ULONG)pDosH + pDosH->e_lfanew);

		PBYTE pb = (PBYTE)pDosH + pNtH->OptionalHeader.BaseOfCode;
		PBYTE pe = pb + pNtH->OptionalHeader.SizeOfCode - 100;
		while ( pb < pe )
		{
			/*
			300910D3 >|> /FF76 1C       push    dword ptr [esi+1C]
			300910D6  |. |68 F8A11A30   push    301AA1F8                    ;  ASCII "url_request"
			300910DB  |. |E8 96D80200   call    <sub_300BE976>
			*/
			if ( 
				pb[0] == 0xff && pb[1] == 0x76 && pb[2] == 0x1c &&
				pb[3] == 0x68 && pb[8] == 0xe8
				)
			{
				__try
				{
					const char* s = *(char**)(pb + 4);
					if ( _stricmp(s, "url_request") == 0 )
					{
						DWORD dwCallOffset, dwWritten;

						dwCallOffset = (DWORD)Dummy_Sub300BE976 - (DWORD)(pb + 8 + 5);
						
						__PatchFlashOcx.PatchedCode = (DWORD)(pb + 9);
						__PatchFlashOcx.sub_300BE976 = *(PDWORD)(pb + 9) + (DWORD)(pb + 8 + 5);
						
						__PatchFlashOcx.bPatched = WriteProcessMemory(
							GetCurrentProcess(), pb + 9, &dwCallOffset, 4, &dwWritten);
						break;
					}
				}
				__except ( EXCEPTION_EXECUTE_HANDLER )
				{
				}
			}

			pb++;
		}
	}
	__except ( EXCEPTION_EXECUTE_HANDLER )
	{
	}

	return __PatchFlashOcx.bPatched;
}

BOOL UnPatchFlashOcx()
{
	if ( __PatchFlashOcx.bPatched )
	{
		DWORD dwWritten;
		DWORD dwOffset = __PatchFlashOcx.sub_300BE976 - __PatchFlashOcx.PatchedCode - 4;

		__PatchFlashOcx.bPatched = !WriteProcessMemory(GetCurrentProcess(), 
			(PVOID)__PatchFlashOcx.PatchedCode, &dwOffset, 4, &dwWritten);
	}

	return !__PatchFlashOcx.bPatched;
}

HMODULE 
WINAPI 
NewLoadLibraryExA(
	LPCSTR lpFileName,
	HANDLE hFile,
	DWORD dwFlags
	)
{
	HMODULE hModule = LoadLibraryExA(lpFileName, hFile, dwFlags);
	if ( hModule != NULL && (dwFlags & LOAD_LIBRARY_AS_DATAFILE) == 0 )
	{
		OutputDebugStringA(lpFileName);

		PCSTR lpName = strrchr(lpFileName, L'\\');
		if ( lpName == NULL )
		{
			lpName = strrchr(lpFileName, L'/');
			if ( lpName == NULL )
				lpName = lpFileName;
		}
		lpName++;
		
		static PCSTR pszFlashOcx[] = {
			"flash9c.ocx", "flash9d.ocx" 
		};
		for ( unsigned i = 0; i < sizeof (pszFlashOcx) / sizeof (pszFlashOcx[0]); i++ )
		{
			if ( stricmp(lpName, pszFlashOcx[i]) == 0 )
			{
				PatchFlashOcx((LPVOID)hModule);
				break;
			}
		}
		
		HookImportTable((LPVOID)hModule, __HookImpStc, sizeof (__HookImpStc) / sizeof (__HookImpStc[0]));
	}
	
	return hModule;
}

HMODULE 
WINAPI 
NewLoadLibraryExW(
	LPCWSTR lpFileName,
	HANDLE hFile,
	DWORD dwFlags
	)
{
	HMODULE hModule = LoadLibraryExW(lpFileName, hFile, dwFlags);
	if ( hModule != NULL && (dwFlags & LOAD_LIBRARY_AS_DATAFILE) == 0 )
	{
		OutputDebugStringW(lpFileName);

		PCWSTR lpName = wcsrchr(lpFileName, L'\\');
		if ( lpName == NULL )
		{
			lpName = wcsrchr(lpFileName, L'/');
			if ( lpName == NULL )
				lpName = lpFileName;
		}
		lpName++;
		
		static PCWSTR pszFlashOcx[] = {
			L"flash9c.ocx", L"flash9d.ocx" 
		};
		for ( unsigned i = 0; i < sizeof (pszFlashOcx) / sizeof (pszFlashOcx[0]); i++ )
		{
			if ( _wcsicmp(lpName, pszFlashOcx[i]) == 0 )
			{
				PatchFlashOcx((LPVOID)hModule);
				break;
			}
		}
		
		HookImportTable((LPVOID)hModule, __HookImpStc, sizeof (__HookImpStc) / sizeof (__HookImpStc[0]));
	}
	
	return hModule;
}

void HookModules(BOOL bHook)
{
	MODULEENTRY32 me;
	me.dwSize = sizeof (me);
	
	HANDLE hModSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
	BOOL bContinue = hModSnap != NULL && Module32First(hModSnap, &me);
	while ( bContinue )
	{
		if ( me.hModule !=__hModule )
		{
			if ( bHook )
			{
				HookImportTable(me.modBaseAddr, __HookImpStc, sizeof (__HookImpStc) / sizeof (__HookImpStc[0]));

				static PCSTR pszFlashOcx[] = {
					_T("flash9c.ocx"), _T("flash9d.ocx") 
				};
				for ( unsigned i = 0; i < sizeof (pszFlashOcx) / sizeof (pszFlashOcx[0]); i++ )
				{
					if ( _tcsicmp(me.szModule, pszFlashOcx[i]) == 0 )
					{
						PatchFlashOcx(me.modBaseAddr);
						break;
					}
				}
			}
			else
			{
				UnHookImportTable(me.modBaseAddr, __HookImpStc, sizeof (__HookImpStc) / sizeof (__HookImpStc[0]));
			}
		}

		bContinue = Module32Next(hModSnap, &me);
	}

	if ( hModSnap != NULL )
	{
		CloseHandle(hModSnap);
	}
}

LRESULT WINAPI MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	return CallNextHookEx(__hMouseHook, nCode, wParam, lParam);
}

BOOL WINAPI InstallMonitor(HWND hWnd)
{
	if ( __hMouseHook == NULL && IsWindow(hWnd) )
	{
		__hWnd = hWnd;
		__hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookProc, __hModule, 0);

		return (__hMouseHook != NULL);
	}
	
	return FALSE;
}

BOOL WINAPI UninstallMonitor()
{
	if ( __hMouseHook != NULL )
	{
		if ( !UnhookWindowsHookEx(__hMouseHook) )
		{
			return FALSE;
		}
		
		__hWnd = NULL;
		__hMouseHook = NULL;
	}
	
	return TRUE;
}

void WINAPI SetMonitorState(int nState)
{
	__nMonitorState = nState;
}

BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID p)
{
	if ( dwReason == DLL_PROCESS_ATTACH )
	{
		__hModule = hModule;

		HMODULE hKnl32Mod = GetModuleHandle(_T("kernel32.dll"));
		__HookImpStc[0].pfnOldProc = GetProcAddress(hKnl32Mod, "LoadLibraryExA");
		__HookImpStc[0].pfnNewProc = (FARPROC)NewLoadLibraryExA;
		__HookImpStc[1].pfnOldProc = GetProcAddress(hKnl32Mod, "LoadLibraryExW");
		__HookImpStc[1].pfnNewProc = (FARPROC)NewLoadLibraryExW;

		HookModules(TRUE);
	}
	else if ( dwReason == DLL_PROCESS_DETACH )
	{
		HookModules(FALSE);
		UnPatchFlashOcx();
	}

	return TRUE;
}

上传的附件:
最新回复 (36)
Fuwa 2007-10-20 23:29
2
喜欢dummy的编程作品
楼主的头像终于变了,呵呵
23
dummy 2007-10-21 09:26
3
都说以前那个头像是鬼,吓走了不少追我的女生
嘿嘿
Fuwa 2007-10-21 09:34
4
其实以前那个我感觉挺酷的,不过这个看着更加舒服些,呵
4
qyc 2007-10-21 10:36
5
强,可整合成IE插件
10
ccfer 2007-10-21 11:24
6
又见超人叔叔
kingofzy 2007-10-21 11:38
7
强,支持。。
21
大菜一号 2007-10-21 11:58
8
`以前的头像是怎么样哒,
7
rick 2007-10-21 12:38
9
哈哈,好东东
7
rick 2007-10-21 12:39
10
一般 flash 中会访问 网站的 xml 获取 信息,能不能把 xml的地址抓出来。
zhtjia 2007-10-21 13:16
11
好帖,顶起来.哈哈
23
dummy 2007-10-21 16:44
12
修改一下 void __stdcall LogOut(PCTSTR pszString) 的过滤条件
26
forgot 2007-10-21 17:05
13
我觉得现在这个头像的脸型更像真人
16
shoooo 2007-10-21 19:51
14
我还以为是抓fly
1
vrowang123 2007-10-21 20:41
15
13
foxabu 2007-10-22 00:54
16


11
火影 2007-10-22 10:03
17
强人啊!
12
monkeycz 2007-10-22 11:24
18
非常同意
23
dummy 2007-10-22 12:32
19
你们这么一说,我发现的确很像。
4
nig 2007-10-22 18:24
20
下载了,多谢,
试试
12
monkeycz 2007-10-22 19:07
21
太无耻了,严重鄙视暗中偷换头像的行为

12
yijun8354 2007-10-22 21:28
22
不错,支持了!
5
bithaha 2007-10-22 21:53
23
下载看看 支持
9
xIkUg 2007-10-22 22:07
24
这个头像够湿。。。不错
3
heXer 2007-10-22 23:14
25
你们这么一说,我发现的确够湿
21
大菜一号 2007-10-23 11:02
26
你这么一说,我发现的确够湿
23
dummy 2007-10-23 12:28
27
我这么一说,发现你们的确够湿
5
bithaha 2007-10-23 15:44
28
优酷视频是flv格式的吗  为什么我安装了以后 播放优酷视频的时候没有反映呀
23
dummy 2007-10-23 17:25
29
下班后回去看一下
jatjtg 2007-10-23 18:06
30
不错,请问用编辑器什么做的??,原谅我笨,菜鸟不大懂,编译
jatjtg 2007-10-23 19:05
31
对了,怎么不能用??
23
dummy 2007-10-23 23:43
32
过滤有点不合适。更新一下
void __stdcall LogOut(PCTSTR pszString)
{
	if ( pszString != NULL )
	{
		if ( StrStrI(pszString, "flv") != NULL ) // 肯定存在不准确性,暂时这样宁可误判,不可误漏
		{
#if 0
			FILE* f = fopen("c:\\getflv.log", "a+");
			if ( f != NULL )
			{
				fprintf(f, "%s\n", pszString);
				fclose(f);
			}
#else
			COPYDATASTRUCT cds;
			
			cds.dwData = 0x8702;
			cds.cbData = strlen(pszString) + 1;
			cds.lpData = (LPVOID)pszString;
			SendMessage(__hWnd, WM_COPYDATA, 0, (LPARAM)&cds);
#endif
		}
	}
}
tanghuiyu 2007-10-30 22:17
33
用VC6.0编译你的源码生成的dll,只对当前已经加载的flash9c.ocx或者flash9d.ocx管用,对新起的浏览器观看flash就没有作用,只有点卸载,安装,然后刷新浏览器才起作用,不过下载你编译好的dll就没有这些问题。呵呵,是不是放上去的代码有问题啊  。
ainwx 2007-11-6 20:31
34
多谢楼主的好文,对我很有启发意义!
23
dummy 2007-11-6 20:33
35
smallworm 2007-12-7 10:36
36
学习了!以前也考虑过这个问题!我的方法是抓网络包!
楼主的方法很巧妙,佩服!
1
jadesoft 2007-12-7 10:49
37
请问能帮我解决以下问题吗?
就是如何得到内存中进程的PE基址以及如何得到svchost.exe,alg.exe以及system的所有者困扰N天了。
帮帮忙
返回