A2Pro THPT Buôn Ma Thuột [2007-2010]


You are not logged in. this website requires you to be logged in. please log in and try again !
A2Pro THPT Buôn Ma Thuột [2007-2010]

Thành lập năm 2008, từng là một diễn đàn lớp với tất cả tình cảm mình gửi gắm vào. Giờ đây là nơi lưu trữ những thứ lặt vặt mình lượm lặt được trong học tập, công việc và cuộc sống !


Share memory in MFC

Share
avatar
ƒ®ï€ñð
Lang thang !!
Lang thang !!

Gender : Nam

Posts Posts : 5165
Thanked : 915
Coins Coins : 11921
Tham Gia : 26/08/2008
Birthday : 05/08/1992

Status Status : 0 - 0 thể - 0 bao giờ ^^

Share memory in MFC

Bài gửi by ƒ®ï€ñð on 1/2/2017, 21:08

File Mapping

http://msdn.microsoft.com/en-us/library/…85%29.aspx
code lấy từ M$,ta sẽ phân tích luôn trong code
Ở process đầu tiên:

Code:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); //tên của vùng nhớ
TCHAR szMsg[]=TEXT("Message from first process.");

int _tmain()
{
  HANDLE hMapFile;
  LPCTSTR pBuf;

  hMapFile = CreateFileMapping(
                INVALID_HANDLE_VALUE,    // use paging file
                NULL,                    // default security
                PAGE_READWRITE,          // read/write access
                0,                       // maximum object size (high-order DWORD)
                BUF_SIZE,                // maximum object size (low-order DWORD)
                szName);                 // name of mapping object

  if (hMapFile == NULL)
  {
     _tprintf(TEXT("Could not create file mapping object (%d).\n"),
            GetLastError());
     return 1;
  }
  pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
                       FILE_MAP_ALL_ACCESS, // read/write permission
                       0,
                       0,
                       BUF_SIZE);
  if (pBuf == NULL)
  {
     _tprintf(TEXT("Could not map view of file (%d).\n"),
            GetLastError());
      CloseHandle(hMapFile);
     return 1;
  }
  CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
   _getch();
  UnmapViewOfFile(pBuf);
  CloseHandle(hMapFile);
  return 0;
}
Ta thấy rằng,ở process trên,khi bắt đầu chạy,hàm CreateFileMapping tạo và mở file để mapping.szName sẽ là tên của vùng nhớ được mapping.Sau đó nếu hàm trả về 1 handle thì ta sẽ dùng hàm MapViewOfFile để pBuf trỏ đến vùng nhớ map file.Việc trỏ đến vùng nhớ chỉ để kiếm tra việc truy xuất vào vùng nhớ có thành công không.

Ở process thứ 2 :
Ta sẽ dùng con trỏ pBuf trỏ đến vùng mapping(theo tên vùng nhớ là szName) rồi xuất ra chuỗi “Message from first process.”

Code:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject");

int _tmain()
{
  HANDLE hMapFile;
  LPCTSTR pBuf;

  hMapFile = OpenFileMapping(
                  FILE_MAP_ALL_ACCESS,   // read/write access
                  FALSE,                 // do not inherit the name
                  szName);               // name of mapping object

  if (hMapFile == NULL)
  {
     _tprintf(TEXT("Could not open file mapping object (%d).\n"),
            GetLastError());
     return 1;
  }

  pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object
              FILE_MAP_ALL_ACCESS,  // read/write permission
              0,
              0,
              BUF_SIZE);

  if (pBuf == NULL)
  {
     _tprintf(TEXT("Could not map view of file (%d).\n"),
            GetLastError());
     CloseHandle(hMapFile);
     return 1;
  }
  MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);
  UnmapViewOfFile(pBuf);
  CloseHandle(hMapFile);
  return 0;
}


Share bằng dll


Khi load dll thì dll chạy thường trực trên hệ thống,vì thế ta có thể dùng để trao đổi dữ liệu thông qua dll

Code:
#pragma comment(linker, "/SECTION:.shared,RWS")
#pragma data_seg(".shared")
bool newMessage = false;
#pragma data_seg()

project demo các bạn down về tại đây :
http://www.mediafire.com/?q16cp84fawcie13

Code của phần này các bạn down từ file đính kèm.

Pipeline(đọc phần process và thread internals)

1 số kỹ thuật khác :


Read và Write vào Process memory
Chương trình khi chạy sẽ có vùng memory riêng,mỗi tiến trình chỉ loay hoay trong 4Gb bộ nhớ ảo của nó,tham chiếu vào vùng khác để đọc ghi là không thể.Tuy nhiên,nếu ta inject vào process khác (bằng hook hoặc sử dụng dll injection) hoạc chuyển privilege của process về debug privilege, hay sử dụng VirtualProtectEx để đặt lại thuộc tính bảo vệ của process đó thì việc Read Write vào memory của process khác là khả thi

Sau đây là ví dụ về việc write process memory.Ta sẽ test với calculator
Ta tìm handle của ứng dụng,rồi dùng hàm WriteProcessMemory để write lại giá trị trong bộ nhớ


Code:
#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
   int newValue = 1000;
   HWND hwnd = FindWindow(0,"Calculator");
   if(hwnd == 0)
   {
       cout << "khong tim thay chuong trinh";
       return 0;
   }
   DWORD pId;
   GetWindowThreadProcessId(hwnd,&pId);
   HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pId);
   
   if(!hProc)
   {
       cout << "khong mo duoc process";
       return 0;
   }
   int test = WriteProcessMemory(hProc,(LPVOID)0x001DC9AC,&newValue,(DWORD)sizeof(newValue),NULL);
   if(!test)
   {
       cout << "khong write duoc";
       return 0;
   }
   cout << "da thay doi gia tri";
   return 0;
}
Chú ý giá trị 0x001DC9AC. Đây chính là địa chỉ logic của ứng dụng.Để tìm ra địa chỉ này có thể dùng 1 số tool như art money hay cheat engine …


Được sửa bởi ƒ®ï€ñð ngày 12/2/2017, 20:10; sửa lần 5.
avatar
ƒ®ï€ñð
Lang thang !!
Lang thang !!

Gender : Nam

Posts Posts : 5165
Thanked : 915
Coins Coins : 11921
Tham Gia : 26/08/2008
Birthday : 05/08/1992

Status Status : 0 - 0 thể - 0 bao giờ ^^

Re: Share memory in MFC

Bài gửi by ƒ®ï€ñð on 1/2/2017, 21:09

Sử dụng Shared memory trong giao tiếp giữa hai Process


Bạn muốn giao tiếp giữa hai process + bạn cần tốc độ nhanh -> giải pháp là sử dụng Shared memory.
Shared memory là một kỹ thuật mà các hệ điều hành cung cấp, được sử dụng với nhiều mục đích trong đó có mục đích trao đổi bản tin giữa hai process chạy trên hệ điều hành.
Với hệ điều hành Windows, giao tiếp giữa hai process sử dụng Shared memory được thực hiện như sau:
Một process tạo một file mapping, gán cho nó một cái tên. File mapping thực chất là một vùng nhớ nằm trong Ram, để map giữa vùng nhớ này và một file trên đĩa.
Hai process sẽ sử dụng vùng nhớ này để trao đổi dữ liệu cho nhau.
Các hàm Windows cung cấp, dùng cho mục đích tạo Shared memory là:

  1. CreateFileMapping - tạo một file mapping với việc chỉ ra tên của nó
  2. MapViewOfFile - Lấy con trỏ trỏ vào vùng nhớ của file mapping
  3. OpenFileMapping - Lấy handle của file mapping, bằng việc chỉ ra tên của nó
  4. CloseHandle - đóng handle dùng để truy cập file mapping

Một vấn đề trong sử dụng Shared memory là đồng bộ. Ở đây là đồng bộ giữa hai process sử dụng chung một vùng nhớ. Ta có thể sử dụng Mutex cho mục đích này.
Các hàm Windows cung cấp để sử dụng Mutex cho mục đích đồng bộ là:

  1. CreateMutex
  2. OpenMutex
  3. WaitForSingleObject
  4. ReleaseMutex

Bạn download thư viện VTSharedMem tại địa chỉ sau VTSharedMem .
Cách sử dụng là build project để thu được 2 file VTSharedMem.lib và VTSharedMem.dll
Trong chương trình của bạn cần #include file VTSharedMem.h
avatar
ƒ®ï€ñð
Lang thang !!
Lang thang !!

Gender : Nam

Posts Posts : 5165
Thanked : 915
Coins Coins : 11921
Tham Gia : 26/08/2008
Birthday : 05/08/1992

Status Status : 0 - 0 thể - 0 bao giờ ^^

Re: Share memory in MFC

Bài gửi by ƒ®ï€ñð on 1/2/2017, 21:27

đây là code của mình
Code:
#include "stdafx.h"

#include<iostream>
#include<winsock2.h>

#pragma comment(lib,"wsock32.lib")

using namespace std;
void hienthi()
{

for(int i=0;i<30;i++)
cout<<endl<<"het cai nay roi"<<endl;

}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE h[100];
DWORD threadId;
h[0]=CreateThread(0,0,(LPTHREAD_START_ROUTINE)hienthi, 0,0,&threadId);
h[1]=CreateThread(0,0,(LPTHREAD_START_ROUTINE)hienthi, 0,0,&threadId);
h[2]=CreateThread(0,0,(LPTHREAD_START_ROUTINE)hienthi, 0,0,&threadId);
h[3]=CreateThread(0,0,(LPTHREAD_START_ROUTINE)hienthi, 0,0,&threadId);
h[4]=CreateThread(0,0,(LPTHREAD_START_ROUTINE)hienthi, 0,0,&threadId);
WaitForMultipleObjects(5,h,TRUE,INFINITE);
return 0;
}
khi mình chạy chương trình này thì đáng lẽ nó hiện thị mỗi cái thì xuống dòng.nhưng do các thread chạy cùng một lúc nên nó lại bị chèm vào nhau như thế này này
Code:
het cai nay roi
het cai nay roi
het cai nay roihet cai nay roihet cai nay roi
het cai nay roi
het cai nay roihet cai nay roihet cai nay roihet cai nay roi
het cai nay roihet cai nay roi
mình biét là phải dùng semaphone hoặc là mutex để giải quyết nhưng mình đã làm mấy hôm rồi không được.mong các bạn giúp đỡ
avatar
ƒ®ï€ñð
Lang thang !!
Lang thang !!

Gender : Nam

Posts Posts : 5165
Thanked : 915
Coins Coins : 11921
Tham Gia : 26/08/2008
Birthday : 05/08/1992

Status Status : 0 - 0 thể - 0 bao giờ ^^

Re: Share memory in MFC

Bài gửi by ƒ®ï€ñð on 1/2/2017, 21:27

nói dùng CreateEvent để xử lý, chỗ này mình không đồng ý, mục đích của CreateEvent là để xử lý đồng bộ ở việc chờ đợi giữa các thread.

Ví dụ đoạn code sau:

void A()
{
Thread[] ListThread; // Danh Sách Các Thread Dùng Đọc File Lớn
ListThread.StartAllThread(); // Start Tất Cả Thread
WaitForAllThread(); // Đợi tất cả thread
DoAfterReadFile(); // Làm việc gì đó sau khi đọc file.
}

Thì lúc này, việc dùng CreateEvent để xử lý cho WaitForAllThread là hợp lý.

Tuy nhiên với đoạn code của ThanSauTK, thì mình nghĩ phải dùng Mutex, bạn chất của Mutex, là để ngăn ngừa nhiều Thread cùng truy xuất đến tài nguyên cùng lúc ( ở đây là cout<<"abc"


Với đoạn code trên, chỗ hàm cout<<"xxx"; ThanSauTK có thể thay thế như sau:
HANDLE hCoutMutex;
DWOD dwWait;
hCoutMuTex = CreateMutex(...)
dwWait = WaitForSingleObject(hCoutMuTex,....);
for(1 -> n)
{
Cout<<""";
}
ReleaseMutex(hCoutMutex);
avatar
ƒ®ï€ñð
Lang thang !!
Lang thang !!

Gender : Nam

Posts Posts : 5165
Thanked : 915
Coins Coins : 11921
Tham Gia : 26/08/2008
Birthday : 05/08/1992

Status Status : 0 - 0 thể - 0 bao giờ ^^

Re: Share memory in MFC

Bài gửi by ƒ®ï€ñð on 1/2/2017, 21:41

Code:
#include <windows.h>
#include <stdio.h>

#define THREADCOUNT 2

HANDLE ghMutex;

DWORD WINAPI WriteToDatabase( LPVOID );

int main( void )
{
    HANDLE aThread[THREADCOUNT];
    DWORD ThreadID;
    int i;

    // Create a mutex with no initial owner

    ghMutex = CreateMutex(
        NULL,              // default security attributes
        FALSE,            // initially not owned
        NULL);            // unnamed mutex

    if (ghMutex == NULL)
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }

    // Create worker threads

    for( i=0; i < THREADCOUNT; i++ )
    {
        aThread[i] = CreateThread(
                    NULL,      // default security attributes
                    0,          // default stack size
                    (LPTHREAD_START_ROUTINE) WriteToDatabase,
                    NULL,      // no thread function arguments
                    0,          // default creation flags
                    &ThreadID); // receive thread identifier

        if( aThread[i] == NULL )
        {
            printf("CreateThread error: %d\n", GetLastError());
            return 1;
        }
    }

    // Wait for all threads to terminate

    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

    // Close thread and mutex handles

    for( i=0; i < THREADCOUNT; i++ )
        CloseHandle(aThread[i]);

    CloseHandle(ghMutex);

    return 0;
}

DWORD WINAPI WriteToDatabase( LPVOID lpParam )
{
    // lpParam not used in this example
    UNREFERENCED_PARAMETER(lpParam);

    DWORD dwCount=0, dwWaitResult;

    // Request ownership of mutex.

    while( dwCount < 20 )
    {
        dwWaitResult = WaitForSingleObject(
            ghMutex,    // handle to mutex
            INFINITE);  // no time-out interval
 
        switch (dwWaitResult)
        {
            // The thread got ownership of the mutex
            case WAIT_OBJECT_0:
                __try {
                    // TODO: Write to the database
                    printf("Thread %d writing to database...\n",
                            GetCurrentThreadId());
                    dwCount++;
                }

                __finally {
                    // Release ownership of the mutex object
                    if (! ReleaseMutex(ghMutex))
                    {
                        // Handle error.
                    }
                }
                break;

            // The thread got ownership of an abandoned mutex
            // The database is in an indeterminate state
            case WAIT_ABANDONED:
                return FALSE;
        }
    }
    return TRUE;
}
avatar
ƒ®ï€ñð
Lang thang !!
Lang thang !!

Gender : Nam

Posts Posts : 5165
Thanked : 915
Coins Coins : 11921
Tham Gia : 26/08/2008
Birthday : 05/08/1992

Status Status : 0 - 0 thể - 0 bao giờ ^^

Re: Share memory in MFC

Bài gửi by ƒ®ï€ñð on 1/2/2017, 21:45

Using the WaitForSingleObject() function and a mutex object in C program example

Code:
// For WinXp as a target, change appropriately
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <stdio.h>
 
BOOL FunctionToWriteSomeData(HANDLE hMutex)
{
DWORD dwWaitResult;
// Request the ownership of mutex...
dwWaitResult = WaitForSingleObject(
hMutex, // handle to mutex
5000L); // five-second time-out interval
 
switch (dwWaitResult)
{
// The thread got the mutex ownership...
case WAIT_OBJECT_0:
// A simple structured exception handling (SEH)...
__try {
printf("The mutex is signaled.\n");
// TODO: Write some data...
}
__finally {
// Release the ownership of the mutex object.
if (!ReleaseMutex(hMutex))
{
// Deal with the error.
printf("ReleaseMutex() failed.\n");
ExitProcess(0);
}
}
// Cannot get the mutex ownership due to time-out.
case WAIT_TIMEOUT:
{
printf("Time-out interval elapsed, and the object's state is signaled (not owned).\n");
printf("Cannot get the mutex ownership\n\n");
return FALSE;
}
 
// Got the ownership of the abandoned mutex object.
case WAIT_ABANDONED:
{
printf("The mutex is set to non-signaled (owned).\n");
printf("Got the mutex...\n");
return FALSE;
}
}
return TRUE;
}
 
// ===================================
int main(void)
{
HANDLE hMutex;
BOOL Test;
// Create a mutex with no initial owner.
hMutex = CreateMutex(
NULL, // no security attributes
FALSE, // initially not owned
L"MutexToProtectSomeData"); // name of mutex
 
if (hMutex == NULL)
{
// Check for error...
printf("CreateMutex() failed, error: %d.\n", GetLastError());
}
else
printf("CreateMutex() is OK.\n");
 
// Write some data function call...
Test = FunctionToWriteSomeData(hMutex);
// Verify the returned value
printf("The function returned value: %d.\n", Test);
return 0;
}

Output example:

Code:
CreateMutex() is OK.
The mutex is signaled.
Time-out interval elapsed, and the object's state is signaled (not owned).
Cannot get the mutex ownership
The function returned value: 0.
Press any key to continue . . .

Sponsored content

Re: Share memory in MFC

Bài gửi by Sponsored content


    Hôm nay: 30/4/2017, 06:13