Ir ao conteúdo
  • Cadastre-se

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


Ir à solução Resolvido por arfneto,

Posts recomendados


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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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;
}

Link para o comentário
Compartilhar em outros sites

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

 

Link para o comentário
Compartilhar em outros sites

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. 

 

 

Link para o comentário
Compartilhar em outros sites

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

Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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. 

Link para o comentário
Compartilhar em outros sites

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.

 

 

 

Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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!