Matrix Posted June 7, 2008 Posted June 7, 2008 Hi Friends I Want Search More Bytes In Any Process With Visual Basic How I Do It ? Please Help ME THanks Sorry For My Bad English
ChupaChu Posted June 7, 2008 Posted June 7, 2008 (edited) basicaly you need to know region you want to search, lets name it bbegin and eendThen you code a simple loop that will read a chunk of data in a variable, thenjust look for accourances of your first byte in your variable - if none then get next chunk (until eend reached)if you got a match (only one - first byte) then you need to do additional comparing to see if other bytes machas well..so basic idea is to have a function that will read data from specified region and use it in a loop.Sorry for not providing any sources, but its better you learn it trying then get it completely served.There are sources of this topic online, just use google.p.s.you can use ReadProcessMemory API for read from memory.BR; ChupaChu! Edited June 7, 2008 by ChupaChu
atom0s Posted June 7, 2008 Posted June 7, 2008 Hey Matrix, I will write you up an example in a sec. I have done this before for some old code but the old code was just tossed together so I will rewrite it and fix it up. Give me a few and I'll post it up.
atom0s Posted June 7, 2008 Posted June 7, 2008 Ok all finished with the rewrite. Project example and code are attached to this post. Heres a quick overview of the example project:'' This example will scan inside of Minesweeper (winmine.exe) on a Windows XP' based system. The given byte array is a call opcode which is located just' after the flag instruction to add or remove a flag when the user right-clicks' on the game board. The actual memory and opcodes looks like this for this' memory section:'' 100346A 8b 44 24 04 mov eax, [esp+04]' 100346E 01 05 94 51 00 01 add [01005194], eax' 1003474 e8 88 f3 ff ff call 01002801' 1003479 c2 04 00 ret 0004'' The below example is told to start scanning at 100346A and scan until' 100346A+3E8 (1000 in hex)'' The ScanForBytes function will locate the process by its name, dump' the given memory based on the start address and size, then compare' the byte array given the memory dump to see if it resides in it.'' This function does not support wild cards and will not deal with dead' memory regions and such on its own. So keep the size that you are scanning' as small as possible and try to limit the address you are scanning to a base' of a region if possible.'' ScanForBytes is setup for parameters like this:'' ScanForBytes(szProcessName As String, dwStartAddr As Long, dwSizeToScan As Long, bByteArrayToScan() As Byte) As Long'' szProcessName - String - Process name to scan for.' dwStartAddr - Long - Start address to start the memory dump from.' dwSizeToScan - Long - Amount of bytes, from the start address, to dump.' bByteArrayToScan - Byte() - Array of bytes to scan for within the memory dump.'' The return value is the address the byte array passed starts at. If the return value is 0' something failed inside the function. You should always compare the return to 0 for error' checking when you are using it in a live program for security and such.'' Hope this helps!'' ~ atomOs'ScanMem.rar
Nacho_dj Posted June 7, 2008 Posted June 7, 2008 Nice code Atomos congratulations. A little question: How fast is this algorithm for searching inside huge blocks of memory? Cheers Nacho_dj
atom0s Posted June 7, 2008 Posted June 7, 2008 I just tested with an allocated block of memory of 1,000,000 bytes which is just about 1 megabyte of memory. I filled the memory with random bytes so its not just dumping 0's as well. Heres my C++ test code to do this:#pragma comment( linker, "/ENTRY:main" )#include <windows.h>#include <stdio.h>int main( int argc, TCHAR* argcv[] ){ LPVOID lpAddr = VirtualAlloc( NULL, 1000000, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); // Fill Memory With Random Bytes for( int x=0; x<=1000000; x++ ) *(BYTE*)((DWORD)lpAddr+x) = (BYTE)rand()%255; printf( "Allocated: %x", lpAddr ); getchar(); VirtualFree( lpAddr, 1000000, MEM_DECOMMIT ); return 0;}I ran the program and let it sit like that so it will hold the memory until I hit enter. Then I opened Cheat Engine, went to the end of the memory block by going to the address printed +1000000 and took the last line of bytes to scan for in the VB app. In this case the last bytes where:&H73, &H5B, &HE0, &HC7, &H1D, &HA7, &H58, &H8A, &H8E, &H64, &H2D, &H27, &HAC, &H71, &H14, &H87, &H88The full line of code was:Private Sub Command1_Click() Dim dwLongRet As Long dwLongRet = ScanForBytes("asdf.exe", &H420000, 1003520, ByteArray(&H73, &H5B, &HE0, &HC7, &H1D, &HA7, &H58, &H8A, &H8E, &H64, &H2D, &H27, &HAC, &H71, &H14, &H87, &H88)) Text1.Text = Hex(dwLongRet)End SubUpon clicking, the return was nearly instant.So I would say safe to assume its pretty fast. If you need to scan for more then one array though, I suggest altering the code and having it dump the memory once, then make another function to scan the dumped block more then once. But its pretty fast.
Matrix Posted June 8, 2008 Author Posted June 8, 2008 Hi Atomos Thanks For YOur SourceBut I Do Not Have Any Address , And I Want Serach Total Of My Process In Memory May You Help Me Again
atom0s Posted June 9, 2008 Posted June 9, 2008 Attached is the new version. This time all you need to pass is the process name and the byte array, for example: ScanForBytes("winmine.exe", ByteArray(&HE8, &H88, &HF3, &HFF, &HFF)) The new function works by looping the processes readable memory regions and dumping them one by one and scanning within them for the given byte array. As far as I know, the memory region code is correct based on comparing the results I obtained to other software that can dump the regions. I've never really worked with them much in the past so I can't guarantee it's perfect. The example, again, scans within Minesweeper for the flag command bytes. Works perfect for me on WinXP Pro w/SP2. Hope this is what you needed. ScanMem_2.rar
Matrix Posted June 9, 2008 Author Posted June 9, 2008 Hi AtomosThanks Very Much DearGo0d Luck My Friend
atom0s Posted June 9, 2008 Posted June 9, 2008 (edited) Not a problem, glad it helps I converted the code to C if anyone wants to use it in C/C++ instead: //// ScanForBytes Memory Region Scanner// Coded By: atomOs (Wiccaan) - 2008// This code is intended to be compiled as 'C' code.//#include <windows.h>#include <stdio.h>#include <tlhelp32.h>unsigned long _GetProcessId( char* szProcName ){ PROCESSENTRY32 pe32; HANDLE hHandle; hHandle = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); pe32.dwSize = sizeof( PROCESSENTRY32 ); if( !Process32First( hHandle, &pe32 ) ) return 0; while( Process32Next( hHandle, &pe32 ) ) { if( strcmp( szProcName, pe32.szExeFile ) == 0 ) { CloseHandle( hHandle ); return pe32.th32ProcessID; } } CloseHandle( hHandle ); return 0;}unsigned long _ScanForBytes( char* szProcess, char* szBytes ){ HANDLE hHandle; SYSTEM_INFO sysInfo; MEMORY_BASIC_INFORMATION mbi; unsigned long dwMemAddr; unsigned long x; hHandle = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ, FALSE, _GetProcessId( szProcess ) ); if( hHandle == INVALID_HANDLE_VALUE || hHandle == NULL ) return 0; GetSystemInfo( &sysInfo ); dwMemAddr = (unsigned long)sysInfo.lpMinimumApplicationAddress; while( dwMemAddr < (unsigned long)sysInfo.lpMaximumApplicationAddress ) { if( VirtualQueryEx( hHandle, (unsigned long*)dwMemAddr, &mbi, sizeof(mbi) ) == sizeof(mbi) ) { if( (mbi.Protect != PAGE_NOACCESS) && (mbi.State == MEM_COMMIT) ) { char* szMemDump = (char*)malloc(mbi.RegionSize+1); ReadProcessMemory( hHandle, (unsigned long*)dwMemAddr, szMemDump, mbi.RegionSize, NULL ); for( x=0; x<mbi.RegionSize; x++ ) { if( memcmp( (void*)(szMemDump+x), (void*)szBytes, strlen( szBytes ) ) == 0 ) { free( szMemDump ); return (unsigned long)( dwMemAddr + x ); } } free( szMemDump ); } } dwMemAddr = (unsigned long)mbi.BaseAddress + mbi.RegionSize; } CloseHandle( hHandle ); return 0;}int main( int argc, TCHAR* argcv[] ){ UNREFERENCED_PARAMETER( argc ); UNREFERENCED_PARAMETER( argcv ); printf( "Scan Results: 0x%08X\n", _ScanForBytes( "winmine.exe", "\xE8\x88\xF3\xFF\xFF" ) ); getchar(); return 0;} Cheers. Edited June 9, 2008 by Atomos
Matrix Posted June 11, 2008 Author Posted June 11, 2008 Hi AtomosI Have A Problem With ScanMem2For Exapmle When I Search "EB FE" In My Process The Return Value Is Not CorrectI Attached My Sample , Pleaes Run Sample And Serach "EB FE" With ScanMem2 Offset Of "EB FE" In This Sample Is "00401C9B" , Test Return Value PleasePlease Help Me AgainThanks DearSample.rar
atom0s Posted June 11, 2008 Posted June 11, 2008 (edited) Hi AtomosI Have A Problem With ScanMem2For Exapmle When I Search "EB FE" In My Process The Return Value Is Not CorrectI Attached My Sample , Pleaes Run Sample And Serach "EB FE" With ScanMem2 Offset Of "EB FE" In This Sample Is "00401C9B" , Test Return Value PleasePlease Help Me AgainThanks DearCould you post your VB project for this? If you need to PM me it if you don't wish to share it with everyone.EDIT: After quickly debugging this I noticed why you are having issues with this. You are doing a compare then having it endlessly loop inside the compare:00401C58 > \8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18]00401C5B . 50 PUSH EAX00401C5C . 68 241A4000 PUSH Sample.00401A24 ; UNICODE "Atomos"00401C61 . FF15 38104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCm>; MSVBVM60.__vbaStrCmp00401C67 . 8BF0 MOV ESI,EAX00401C69 . 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]00401C6C . F7DE NEG ESI00401C6E . 1BF6 SBB ESI,ESI00401C70 . 46 INC ESI00401C71 . F7DE NEG ESI00401C73 . FF15 88104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeS>; MSVBVM60.__vbaFreeStr00401C79 . 8D4D E4 LEA ECX,DWORD PTR SS:[EBP-1C]00401C7C . FF15 8C104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeO>; MSVBVM60.__vbaFreeObj00401C82 . B9 04000280 MOV ECX,8002000400401C87 . B8 0A000000 MOV EAX,0A00401C8C . 66:3BF7 CMP SI,DI00401C8F . 894D AC MOV DWORD PTR SS:[EBP-54],ECX00401C92 . 8945 A4 MOV DWORD PTR SS:[EBP-5C],EAX00401C95 . 894D BC MOV DWORD PTR SS:[EBP-44],ECX00401C98 . 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX00401C9B >- EB FE JMP SHORT Sample.00401C9BHaving the EB FE inside this will never return a value as it will just get stuck at that JMP. Edited June 11, 2008 by Atomos
Matrix Posted June 11, 2008 Author Posted June 11, 2008 Hi AtomosThis File Is Just An Example And Not ImportantFor Exaplme I Want When Using Your ScanMem2 For Search "EB FE" ,The Return Value Equal 401C9B Can You Help Me Dear ?
atom0s Posted June 11, 2008 Posted June 11, 2008 The return I get scanning inside of the Sample.exe is 14D042 which in theory is correct as that opcode does contain the bytes you are telling it to scan for. Instead, are you able to add more bytes to the string to scan for? It would be better if you could use more instead of just a few. It would limit the amount of same matches found.For example, the opcodes around 401C9B are 00401C8C . 66:3BF7 CMP SI,DI00401C8F . 894D AC MOV DWORD PTR SS:[EBP-54],ECX00401C92 . 8945 A4 MOV DWORD PTR SS:[EBP-5C],EAX00401C95 . 894D BC MOV DWORD PTR SS:[EBP-44],ECX00401C98 . 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX00401C9B >- EB FE JMP SHORT Sample.00401C9B00401C9D . 8B35 74104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVa>; MSVBVM60.__vbaVarDup00401CA3 . BB 08000000 MOV EBX,800401CA8 . 8D55 84 LEA EDX,DWORD PTR SS:[EBP-7C]00401CAB . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]00401CAE . C745 8C 581A4>MOV DWORD PTR SS:[EBP-74],Sample.00401A5>; UNICODE "Success"00401CB5 . 895D 84 MOV DWORD PTR SS:[EBP-7C],EBX00401CB8 . FFD6 CALL ESI ; <&MSVBVM60.__vbaVarDup>To add to it, you could do the instruction before it as well. For this example I'd use:00401C98 . 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX00401C9B >- EB FE JMP SHORT Sample.00401C9B00401C9D . 8B35 74104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVa>; MSVBVM60.__vbaVarDupSo our byte array would be:&H89, &H45, &HB4, &HEB, &HFE, &H8B, &H35, &H74, &H10, &H40, &H00Then the code would be: Dim dwAddress As Long dwAddress = ScanForBytes("Sample.exe", ByteArray(&H89, &H45, &HB4, &HEB, &HFE, &H8B, &H35, &H74, &H10, &H40, &H0)) Text1.Text = Hex(dwAddress)Which returns: 401C98Then you can add onto the return based on the number of bytes you used before the real ones, so we would add +3 to the return for the actual address. You don't need that many bytes either, instead you could shorten it to the instruction before as well.
JohnWho Posted June 12, 2008 Posted June 12, 2008 00401C98 . 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX00401C9B >- EB FE JMP SHORT Sample.00401C9B00401C9D . 8B35 74104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVa>; MSVBVM60.__vbaVarDupSo our byte array would be:&H89, &H45, &HB4, &HEB, &HFE, &H8B, &H35, &H74, &H10, &H40, &H00If the byte pattern to search for is supposed to be universal/generic it's a bad idea searching on a DWORD!JW.
Matrix Posted June 12, 2008 Author Posted June 12, 2008 The return I get scanning inside of the Sample.exe is 14D042 which in theory is correct as that opcode does contain the bytes you are telling it to scan for. Instead, are you able to add more bytes to the string to scan for? It would be better if you could use more instead of just a few. It would limit the amount of same matches found.For example, the opcodes around 401C9B are 00401C8C . 66:3BF7 CMP SI,DI00401C8F . 894D AC MOV DWORD PTR SS:[EBP-54],ECX00401C92 . 8945 A4 MOV DWORD PTR SS:[EBP-5C],EAX00401C95 . 894D BC MOV DWORD PTR SS:[EBP-44],ECX00401C98 . 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX00401C9B >- EB FE JMP SHORT Sample.00401C9B00401C9D . 8B35 74104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVa>; MSVBVM60.__vbaVarDup00401CA3 . BB 08000000 MOV EBX,800401CA8 . 8D55 84 LEA EDX,DWORD PTR SS:[EBP-7C]00401CAB . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]00401CAE . C745 8C 581A4>MOV DWORD PTR SS:[EBP-74],Sample.00401A5>; UNICODE "Success"00401CB5 . 895D 84 MOV DWORD PTR SS:[EBP-7C],EBX00401CB8 . FFD6 CALL ESI ; <&MSVBVM60.__vbaVarDup>To add to it, you could do the instruction before it as well. For this example I'd use:00401C98 . 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX00401C9B >- EB FE JMP SHORT Sample.00401C9B00401C9D . 8B35 74104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVa>; MSVBVM60.__vbaVarDupSo our byte array would be:&H89, &H45, &HB4, &HEB, &HFE, &H8B, &H35, &H74, &H10, &H40, &H00Then the code would be: Dim dwAddress As Long dwAddress = ScanForBytes("Sample.exe", ByteArray(&H89, &H45, &HB4, &HEB, &HFE, &H8B, &H35, &H74, &H10, &H40, &H0)) Text1.Text = Hex(dwAddress)Which returns: 401C98Then you can add onto the return based on the number of bytes you used before the real ones, so we would add +3 to the return for the actual address. You don't need that many bytes either, instead you could shorten it to the instruction before as well.Hi My FriendI Want Use This Method For Detecting Sniffer , Because Sniffer Write "EB FE" In Your Process For Example For Reading Registers (EAX, EBX,...) For Finding Correct Serial .Now I Search "EB FE" In My Process I Can Know That My Program Run With A Serial SnifferI Just Find "EB FE"Thanks Dear
atom0s Posted June 14, 2008 Posted June 14, 2008 If the byte pattern to search for is supposed to be universal/generic it's a bad idea searching on a DWORD!JW. Yes I know, I was just trying to point out what I meant by using bytes around the given pattern. Searching for specific addresses is something I'd use wildcards for. Hi My FriendI Want Use This Method For Detecting Sniffer , Because Sniffer Write "EB FE" In Your Process For Example For Reading Registers (EAX, EBX,...) For Finding Correct Serial .Now I Search "EB FE" In My Process I Can Know That My Program Run With A Serial Sniffer I Just Find "EB FE" Thanks Dear I'm not too sure what you mean by 'detecting sniffer'. The code I gave above will scan for the bytes as needed in each section, I can't really give much more help other then what I have given a I do not really know much about the target you are working on or what the exact problem you are facing is.
Departure Posted July 1, 2008 Posted July 1, 2008 anyone got an example in delphi to scan for bytes>?
JohnWho Posted July 10, 2008 Posted July 10, 2008 anyone got an example in delphi to scan for bytes>?Here's a very basic and raw example >http://rapidshare.com/files/128644983/ProcessScan.rar.htmlHope this is what you need.JW.
Departure Posted October 28, 2008 Posted October 28, 2008 thanks for the delphi example JohnWho, its very slow but im sure with some modifycations it should speed it up
JohnWho Posted October 30, 2008 Posted October 30, 2008 thanks for the delphi example JohnWho, its very slow but im sure with some modifycations it should speed it upThreading it helps a bit!
Nieylana Posted December 5, 2008 Posted December 5, 2008 Hi FriendsI Want Search More Bytes In Any Process With Visual Basic How I Do It ? Please Help ME THanks Sorry For My Bad English when i can i will upload my clsQuickSearch which does exactly what you need, or better yet you can download my WTLoader from the ToolsOfTrade section and get it inside the source folder
david_2000 Posted October 3, 2009 Posted October 3, 2009 hi guysand thanks to atom0s for his great example.1 question to atom0s:is there a way to make it search just in one module?for example i just want to search just in user32.dll not other modules.is these possible with your byte scanner example?waiting for your replay.thanks.
atom0s Posted October 3, 2009 Posted October 3, 2009 hi guysand thanks to atom0s for his great example.1 question to atom0s:is there a way to make it search just in one module?for example i just want to search just in user32.dll not other modules.is these possible with your byte scanner example?waiting for your replay.thanks.Which example are you referring to? I posted a few different ones in this topic.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now