Ir ao conteúdo

C++ o que está errado nessa função


Ir à solução Resolvido por arfneto,

Posts recomendados

Postado


o problema é que sempre imprime 0 

 

    #include <tchar.h>
    #include <windows.h>
    #include <TlHelp32.h>
    #include <iostream>
    #include <Psapi.h>
    #include <wchar.h>
    using namespace std;

    uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName){
    uintptr_t modBaseAddr = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if (Module32First(hSnap, &modEntry))
        {
            do
            {
                if (!_wcsicmp((const wchar_t*)modEntry.szModule,modName))
                {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnap, &modEntry));
        }
    }
    CloseHandle(hSnap);
    return modBaseAddr;
}

	int main(){
    HWND GameHWND = FindWindow(0, "Mario");
    DWORD procId = 0;
    GetWindowThreadProcessId(GameHWND, &procId);
    std::cout<<"ProcID "<< procId << std::endl;
     //Getmodulebaseaddress
    uintptr_t moduleBase = GetModuleBaseAddress(procId,L"Mario.exe");
    std::cout<<"Modulebase "<< moduleBase<< std::endl;
}

 

  • Curtir 1
Postado

Mas você nem testa se FindWindow() conseguiu um handle e segue adiante... Achar janelas pelo título é inseguro eu acho.

Teste o retorno antes de seguir. acho que não está retornando o Handle.

Meses atrás postei um programa aqui neste forum que levanta a lista de processos no Windows, usando uma técnica mais segura talvez: o simples de criar uma lista dos processos que estão rodando e percorrer a lista em busca do que precisa. Talvez ache mais seguro usar algo assim. Pode ver em Task List

  • Curtir 3
Postado

O problema é que a função _wcsicmp() está comparando duas strings de tipos diferentes: o argumento modName (que é do tipo wchar_t) e o campo szModule da estrutura modEntry, que o teu compilador está tratando como sendo do tipo char* (Ansi).
Uma maneira de resolver isso é forçando a declaração da estrutura modEntry como sendo do tipo Unicode e chamando suas respectivas funções Unicode para a mesma. É só adicionar um W no fim de cada termo, assim:

MODULEENTRY32W modEntry;
Module32FirstW()
Module32NextW()

  • Curtir 2
Postado
14 minutos atrás, holifaca disse:

O problema é que a função _wcsicmp() está comparando duas strings de tipos diferentes: o argumento modName (que é do tipo wchar_t) e o campo szModule da estrutura modEntry, que o teu compilador está tratando como sendo do tipo char* (Ansi).
Uma maneira de resolver isso é forçando a declaração da estrutura modEntry como sendo do tipo Unicode e chamando suas respectivas funções Unicode para a mesma. É só adicionar um W no fim de cada termo, assim:


MODULEENTRY32W modEntry;
Module32FirstW()
Module32NextW()

 

 

Entenda que se FindWindow não voltar com um Handle de nada adianta continuar... E o programa não testa.

  • Curtir 2
Postado
46 minutos atrás, arfneto disse:

 

Entenda que se FindWindow não voltar com um Handle de nada adianta continuar... E o programa não testa.

Mesmo assim há ainda um problema de compatibilidade na codificação de caracteres no código dele. Perceba que ele chama FindWindow() passando uma string no formato Ansi (char*) e o código compila  normalmente, o que indica que o compilador está tratando todas as chamadas APIs do Windows usando aquele charset. Já dentro da função GetModuleBaseAddress(), ele utiliza a estrutura modEntry sem especificar o charset, e aí o compilador trata ela como sendo Ansi, e quando chega na comparação das strings, que usa uma função Unicode, ele tenta converter a string char* em const wchar_t*, o que é errado! Para converter uma string tradicional do C em Unicode é necessário criar uma função para isso e não simplesmente usar um type casting.

  • Curtir 2
Postado
14 minutos atrás, Mayrinck Bernardo disse:

tinha esquecido mesmo mas o problema continua sempre da 0 mesmo o processo rodando

 

Mas está achando ou não a janela? Testou o retorno de FindWindow? Use L"" para o título.

 

Rodou o programa de que e falei? Procurar janelas pelo título não é seguro.

Crie a lista de processos e encontre o que quer na lista. Use CreateToolhelp32Snapshot() como no exemplo do programa que eu escrevi

  • Curtir 2
Postado

1-Rode o programa como administrador do sistema.
2-O ID do processo está retornando corretamente?

3-O teu programa funciona com a calculadora do Windows? Teste aí usando: "Calculadora" e  L"calc.exe".
4-Esse jogo Mario é protegido por algum aplicativo tipo Gameguard, HShield, etc?

  • Curtir 2
Postado

sim

image.png.99a65fecf50e6cde02e8293ec7b10cca.png

    #include <tchar.h>
    #include <windows.h>
    #include <TlHelp32.h>
    #include <iostream>
    #include <Psapi.h>
    #include <wchar.h>
    using namespace std;


    uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName){
    uintptr_t modBaseAddr = 0;

    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32W modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if (Module32FirstW(hSnap, &modEntry))
        {
            do
            {
                if (!_wcsicmp(modEntry.szModule,modName))
                {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while (Module32NextW(hSnap, &modEntry));
        }
    }
    //CloseHandle(hSnap);
    return modBaseAddr;
}

	int main(){
    HWND GameHWND = FindWindow(0,"calculadora");
    DWORD procId = 0;
    GetWindowThreadProcessId(GameHWND, &procId);
    std::cout<<"ProcID "<< procId << std::endl;
     //Getmodulebaseaddress
    uintptr_t moduleBase = GetModuleBaseAddress(procId, L"calc.exe");
    std::cout<<"Modulebase "<< moduleBase<< std::endl;
    cin.ignore();
}

 

adicionado 0 minutos depois

o jogo estava fechado quando fiz isso agora

  • Curtir 1
Postado

Teste o código abaixo e poste a saída completa:


#include <tchar.h>
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <Psapi.h>
#include <wchar.h>
using namespace std;

uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
    uintptr_t modBaseAddr = 0;

    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32W modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if (Module32FirstW(hSnap, &modEntry))
        {
            do
            {
                printf("szModule: %S\n", modEntry.szModule);
                if (!_wcsicmp(modEntry.szModule,modName))
                {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while (Module32NextW(hSnap, &modEntry));
        }
        else
        {
            cout<<"erro Module32FirstW(): "<<GetLastError()<<endl;
        }
        CloseHandle(hSnap);
    }
    else
        cout<<"erro CreateToolhelp32Snapshot(): "<<GetLastError()<<endl;
    return modBaseAddr;
}

int main(){
    HWND GameHWND = FindWindow(0,"calculadora");
    if (GameHWND == NULL) {
        cout<<"erro FindWindow(): "<<GetLastError()<<endl;
        return 1;
    }
    DWORD procId = 0;
    GetWindowThreadProcessId(GameHWND, &procId);
    std::cout<<"ProcID "<< procId << std::endl;
     //Getmodulebaseaddress
    uintptr_t moduleBase = GetModuleBaseAddress(procId, L"calc.exe");
    std::cout<<"Modulebase "<< moduleBase<< std::endl;
    cin.ignore();
    return 0;
}

Postado

image.png.77d6fe0103218d854d8d2ad2097440d5.png

adicionado 0 minutos depois
ProcID 3020
szModule: ApplicationFrameHost.exe
szModule: ntdll.dll
szModule: KERNEL32.DLL
szModule: KERNELBASE.dll
szModule: msvcrt.dll
szModule: combase.dll
szModule: ucrtbase.dll
szModule: RPCRT4.dll
szModule: bcryptPrimitives.dll
szModule: dxgi.dll
szModule: win32u.dll
szModule: gdi32.dll
szModule: gdi32full.dll
szModule: msvcp_win.dll
szModule: USER32.dll
szModule: dxcore.dll
szModule: cfgmgr32.dll
szModule: IMM32.DLL
szModule: kernel.appcore.dll
szModule: ApplicationFrame.dll
szModule: SHCORE.dll
szModule: SHLWAPI.dll
szModule: PROPSYS.dll
szModule: OLEAUT32.dll
szModule: sechost.dll
szModule: twinapi.appcore.dll
szModule: UxTheme.dll
szModule: bcp47mrm.dll
szModule: DEVOBJ.dll
szModule: TWINAPI.dll
szModule: d2d1.dll
szModule: dwmapi.dll
szModule: RMCLIENT.dll
szModule: d3d11.dll
szModule: OneCoreUAPCommonProxyStub.dll
szModule: MSCTF.dll
szModule: ADVAPI32.dll
szModule: D3D10Warp.dll
szModule: dcomp.dll
szModule: CoreMessaging.dll
szModule: UIAutomationCore.DLL
szModule: SHELL32.dll
szModule: windows.storage.dll
szModule: profapi.dll
szModule: powrprof.dll
szModule: UMPDC.dll
szModule: cryptsp.dll
szModule: windows.staterepositorycore.dll
szModule: windowscodecs.dll
szModule: Windows.StateRepositoryPS.dll
szModule: mrmcorer.dll
szModule: iertutil.dll
szModule: Bcrypt.dll
szModule: Windows.UI.dll
szModule: TextInputFramework.dll
szModule: InputHost.dll
szModule: CoreUIComponents.dll
szModule: ntmarta.dll
szModule: wintypes.dll
szModule: UIAnimation.dll
szModule: rometadata.dll
szModule: OneCoreCommonProxyStub.dll
szModule: ActXPrxy.dll
Modulebase 0

 

Postado
1 hora atrás, Mayrinck Bernardo disse:

fiz todos testes que mandou e continua dando 0, não sei o que fazer, tanto a calculadora quanto a jogo

 

Rodou o programa que te mostrei? crie um snapshot e um loop na lista de processos vai te mostrar o pId do processo que quer. Aí pode ver na lista daquele processo TODOS os handles d processo, incluindo as janelas abertas... É o caminho comum. Acho que todos os programas desse tipo fazem isso. 

 

 

Postado

A calculadora do Win10 é desenvolvida em UVP e é diferente da plataforma Win32. Que azar! :(

A saída do jogo também inicia com ApplicationFrameHost.exe? Sabe dizer em qual linguagem ele foi feito?

Postado
3 horas atrás, arfneto disse:

Rodou o programa que te mostrei?

sim eu ainda tenho ele guardado aqui desde que você postou a primeira vez, se eu for modifica-lo agora vou demorar queria resolver logo o problema pra depois fazer algo mais elegante.

 

adicionado 2 minutos depois
3 horas atrás, holifaca disse:

A calculadora do Win10 é desenvolvida em UVP e é diferente da plataforma Win32. Que azar!

então essa função so consegue os apps que foram desenvolvidos antigamente?

3 horas atrás, holifaca disse:

A calculadora do Win10 é desenvolvida em UVP e é diferente da plataforma Win32. Que azar! :(

A saída do jogo também inicia com ApplicationFrameHost.exe? Sabe dizer em qual linguagem ele foi feito?

eu não sei a linguagem, mas tenho outros jogos que queria aplicar a técnica, funcionando em algum está bom pra mim

Postado
agora, Mayrinck Bernardo disse:

então essa função so consegue os apps que foram desenvolvidos antigamente?

eu não sei a linguagem, mas tenho outros jogos que queria aplicar a técnica, funcionando em algum está bom pra mim

Sim, essa função só funciona com programas alvos desenvolvidos em .NET e Win32 (funciona tanto em Windows de 32bits como em 64bits). Faça um teste com outros programas aí pra ver.

  • Curtir 1
Postado
3 horas atrás, holifaca disse:

Sim, essa função só funciona com programas alvos desenvolvidos em .NET e Win32 (funciona tanto em Windows de 32bits como em 64bits). Faça um teste com outros programas aí pra ver.

hmm é bom saber disso mas creio que o problema é um pouco mais grave tentei fazer isso com um jogo que tenho aqui que foi desenvolvido em c++ e não funcionou nem em uma versão antiga nem na atual, e tambem em nehum outro mas nao vou desistir vou continuar tentando agradeço a ajuda. 

Postado
10 minutos atrás, Mayrinck Bernardo disse:

hmm é bom saber disso mas creio que o problema é um pouco mais grave tentei fazer isso com um jogo que tenho aqui que foi desenvolvido em c++ e não funcionou nem em uma versão antiga nem na atual, e tambem em nehum outro mas nao vou desistir vou continuar tentando agradeço a ajuda

 

Use as estruturas do sistema. Elas vão funcionar para qualquer aplicação, qualquer framework e qualquer ferramenta.

 

 

 

Postado

Essa parte ainda não foi traduzida, mas está descrito aqui: https://docs.microsoft.com/pt-br/windows/win32/sysinfo/handles-and-objects

 

Uma janela é uma janela, não importa como foi escrita. Tem um Handle. Fica num desktop. Que tem um Handle.  Ela tem um Handle e foi criada por um processo. Um thread de um processo, que tem um pai. E então tem um Handle também. E o Handle leva a uma estrutura que descreve o processo. E lá está o nome do executável que criou a janela. Um Handle é um int.

 

Rode esse programa em sua máquina

#pragma once

#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <psapi.h>

#include "stdio.h"
#include "stdlib.h"

int CALLBACK agente(HWND, LPARAM);

int main(int argc, char** argv)
{
    DWORD flags = 0;
    int  inherit = 0;
    ACCESS_MASK access = READ_CONTROL;
    HDESK desktop = OpenInputDesktop(flags, inherit, access);
    if (desktop == NULL) return -1;
    EnumDesktopWindows(desktop, agente, 0);
    return 0;
};  // main()

int CALLBACK agente(HWND H, LPARAM P)
{
    char    buffer[512];
    DWORD   pai;
    LPDWORD pId = &pai;
    int n = GetWindowTextLengthA(H);
    char* titulo = malloc(1 + n);
    GetWindowTextA(H, titulo, 1 + n);
    DWORD   window_thread = GetWindowThreadProcessId(H, pId);
    ACCESS_MASK access =
        PROCESS_QUERY_INFORMATION |
        PROCESS_VM_READ;
    HANDLE hProcess = OpenProcess(access, FALSE, pai);
    if (hProcess == NULL) return -1;
    n = GetProcessImageFileNameA(hProcess, buffer, 512);
    if (n <= 0) return -2;
    char* p = buffer;
    for (int i = n; i > 1; i-=1)
    {
        if (buffer[i] != '\\') continue;
        p = buffer + i + 1;
        break;
    }   // for()
    if (strlen(titulo) > 0)
        printf("Window thread: %8d\ttitulo: '%s'\n\tpai:%8d\tExe: '%s'\n",
            window_thread, titulo, pai, p);
    else
        printf("Window thread: %8d\tpai:%8d\tExe: '%s'\n",
            window_thread, pai, p);
    free(titulo);
    return 1;
};  // agente()

Ele segue esse caminho que eu expliquei. Deve ajudar a entender.

 

O que faz o programa?

  • identifica o desktop e
  • para cada janela
  • vê o tamanho do titulo da janela. Pode ser zero. E
  • lê o título da janela
  • abre o processo que criou a janela
  • encontra o pai dele
  • identifica o executável
  • mostra os dados na tela

E poste seu código como está pra eu poder ver se entendo o que falta.

 

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!