djevil-ad
Goto Top

Parameter mit argv übergeben in C-Programm

Hallo, ich mochte einen Parameter an eine Variable übergeben:

int main(int argc, char* argv) 
{
	
	INPUT ip;
	printf(argv[1]);

	
    // Set up a generic keyboard event.
    ip.type = INPUT_KEYBOARD;
    ip.ki.wScan = 0; // hardware scan code for key
    ip.ki.time = 0;
    ip.ki.dwExtraInfo = 0;
 
    // Press the "A" key  
    ip.ki.wVk = argv[1]; // virtual-key code for the "a" key 0x41  

Wenn ich

printf(argv[1]);

aufrufe funktioniert es, wenn ich aber

ip.ki.wVk = argv[1];

in die Variable schreiben will geht es nicht?

Fehlermeldung:

assignment makes integer from pointer without a cast [enabled by default]

der parameter argv[1] soll 0x41 übergeben, also programmname.exe 0x41

Ich bin leider kein C-Programmierer und steig da nicht durch.., aber 0x41 ist doch kein integer

Content-ID: 259939

Url: https://administrator.de/contentid/259939

Ausgedruckt am: 15.11.2024 um 11:11 Uhr

114757
114757 15.01.2015, aktualisiert am 16.01.2015 um 10:28:27 Uhr
Goto Top
Moin,
vermutlich erwartet die Variable ip.ki.wVk einen Pointer face-wink

http://charlottehill.com/error/2018.xml

Gruß jodel32
116301
116301 16.01.2015 um 01:37:40 Uhr
Goto Top
Hallo djevil-ad!

vermutlich erwartet die Variable ip.ki.wVk einen Pointer
Ist ja ein Pointer und so wie ich das sehe will die Variable ja einen Key-Codeface-wink

Grundsätzlich werden Argumente als ASCII-Zeichen übergeben und müssen je nach Bedarf entsprechend konvertiert werden.
Argv ist eine Pointer-Strukt d.h. Pointer auf Argv der in Argv, Argv[1]... wiederum Pointer auf die einzelnen Argumente beinhaltet.

Wenn Du ein "A" als Argument übergibst, dann bekommst Du über Argv[1] den Buchstaben "A" als Char und wenn Du 0x41 als Argument übergibst, dann bekommst Du dieses ebenfalls als Char "0x41", wobei das "A" in der Byte-Arbeitsspeicheradresse als Hex-Wert 0x41 (dezimal 65) steht. Wenn Du einen Integer brauchst, dann musst Du den Char "A" in einen Integer konvertieren. Bei einem einzelnen Buchstaben sollte es mit = (int) argv[1] möglicherweise auch gehen...

Hexzahlen werden im Format 0x.. angegeben und werden nur innerhalb des Programmcodes als Zahlen interpretiert (Integer, Long...)

Test mal:
ip.ki.wVk = 0x41;

Grüße Dieter
djevil-ad
djevil-ad 16.01.2015 um 10:52:36 Uhr
Goto Top
@114757

Welches Beispiel davon meinst du?

@116301

Test mal:
ip.ki.wVk = 0x41;

Nein, 0x41 soll ja als parameter argv übergeben werden.

Aber wenn ich dich richtig verstehe ist es einfacherl den Parameter als A zu übergeben da dieser dann als 0x41 in den Speicher geschrieben wird.

Habe jetzt geschrieben:

ip.ki.wVk = (*argv[1]);

Da muss ich aber ein A eingeben um ein a zu erhalten...?

Vielleicht ist eiener so nett mir zu sagen wie man es richtig machen würde,
Ich brauch wirklich nur dieses eine programm, da macht es nicht viel Sinn mich allzutief in C einzuarbeiten.
djevil-ad
djevil-ad 16.01.2015 um 10:58:24 Uhr
Goto Top
Edit: nein ich muss ja doch die Keycodes als hex-Werte angeben, wegen der Sonderzeichen.
114757
114757 16.01.2015 aktualisiert um 11:10:06 Uhr
Goto Top
Es wäre mal schön zu wissen von welchem Typ die Variable ip.ki.wVk ist (steht entweder irgendwo in deinem Code oder in der Bibliothek die du benutzt) !
Eine Typumwandlung machst du beispielsweise so:

ip.ki.wVk  = (int*)argv[1];
oder
ip.ki.wVk  = (char*)argv[1];
Ohne den Typ deiner Variablen zu kennen ... ist das hier leider ein Raten ....

Gruß jodel32
djevil-ad
djevil-ad 16.01.2015 um 11:42:37 Uhr
Goto Top
Das ist der komplette Code:

#define WINVER 0x0602
#include <windows.h>


int main(int argc, char* argv)
{

INPUT ip;

Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0;
hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

Press the "A" key
ip.ki.wVk = (*argv[1]);
virtual-key code for the "a" key 0x41
ip.ki.dwFlags = 0; 0 for key press
SendInput(1, &ip, sizeof(INPUT));

Release the "A" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));

Exit normally
return 0;
}
djevil-ad
djevil-ad 16.01.2015 um 21:51:27 Uhr
Goto Top
Ok, der Typ muss ein Word sein, also
muss char in word konvertieren? Aber wie?
rubberman
rubberman 16.01.2015 um 23:05:28 Uhr
Goto Top
Hallo djevil-ad.

Ich bin leider kein C-Programmierer und steig da nicht durch..
Warum willst du dann einen Klickbot in C programmieren?

aber 0x41 ist doch kein integer
Kommt auf den Kontext an. 0x41 ist die hexadezimale Schreibweise für 65. Warum sollte es also kein Integer sein?
Dein Denkfehler ist allerdings, dass numerische Argumente auch als Zahl eingehen. Dem ist nicht so. Wie du in der Parameterliste der main() Funktion sehen kannst, kommen Argumente als Array von Charpointern an. (In anderen Sprachen würde man von einem Stringarray reden, in C gibt es aber keinen Stringtyp.) Du musst also vorab konvertieren. Ich schlage die strtol() Funktion zu diesem Zweck vor.

Grüße
rubberman
114757
Lösung 114757 16.01.2015, aktualisiert am 17.01.2015 um 11:14:46 Uhr
Goto Top
also dann noch ein
#include <stdlib.h>
in den Kopf und dann
ip.ki.wVk = strtol(argv[1],NULL,0);

Gruß jodel32
rubberman
rubberman 17.01.2015 aktualisiert um 01:56:52 Uhr
Goto Top
Naja, so ähnlich. Letztlich bietet strtol() die Möglichkeit Falscheingaben abzufangen, was den eigentlichen Reiz ausmacht.

Ich würde den Spaß etwa so schreiben:
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef _UNICODE
#undef _UNICODE
#endif

#ifdef WINVER
#undef WINVER
#endif
#define WINVER 0x0501
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0501

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char *argv)
{
  long lConverted = 0;
  char *pchEnd = 0,
       szCurrentKbLayout[KL_NAMELENGTH] = {0};
  HKL hkl = NULL;
  INPUT ip[8] = {{0}};
  int i = 0, j = 0, c = 0, ch = EOF;
  SHORT sKey = 0;
  UINT uScShift = 0,
       uScCtrl = 0,
       uScAlt = 0,
       uCapslock = 0,
       rguScanCodes[4] = {0};

  if (argc != 2)
    return 1;

  errno = 0;
  lConverted = strtol(argv[1], &pchEnd, 0);
  if (*pchEnd || ERANGE == errno || lConverted < 0 || lConverted > 255)
    return 1;

  ch = (int)lConverted;

  BOOL fCapslock = GetKeyState(VK_CAPITAL) & 1;

  if (!GetKeyboardLayoutName(szCurrentKbLayout))
    return 1;

  hkl = LoadKeyboardLayout(szCurrentKbLayout, KLF_ACTIVATE | KLF_NOTELLSHELL | KLF_REPLACELANG | KLF_SETFORPROCESS);

  uScShift = MapVirtualKeyEx(VK_SHIFT, MAPVK_VK_TO_VSC, hkl),
  uScCtrl = MapVirtualKeyEx(VK_CONTROL, MAPVK_VK_TO_VSC, hkl),
  uScAlt = MapVirtualKeyEx(VK_MENU, MAPVK_VK_TO_VSC, hkl),
  uCapslock = MapVirtualKeyEx(VK_CAPITAL, MAPVK_VK_TO_VSC, hkl);

  for (; i < 8; ++i)
  {
    ip[i].type = INPUT_KEYBOARD;
    ip[i].ki.time = 0;
    ip[i].ki.wVk = 0;
    ip[i].ki.dwExtraInfo = 0;
    ip[i].ki.dwFlags = KEYEVENTF_SCANCODE;
  }

  if (fCapslock)
  {
    ip.ki.dwFlags &= ~KEYEVENTF_KEYUP;
    ip.ki.wScan = uCapslock;
    ip[1].ki.dwFlags |= KEYEVENTF_KEYUP;
    ip[1].ki.wScan = uCapslock;
    SendInput(2, ip, sizeof(INPUT));
  }

  if ((sKey = VkKeyScanEx(ch, hkl)) == (SHORT)(-1))
    return 1;

  if (HIBYTE(sKey) & 1)
    rguScanCodes[c++] = uScShift;
  if (HIBYTE(sKey) & 2)
    rguScanCodes[c++] = uScCtrl;
  if (HIBYTE(sKey) & 4)
    rguScanCodes[c++] = uScAlt;
  rguScanCodes[c++] = MapVirtualKeyEx(LOBYTE(sKey), MAPVK_VK_TO_VSC, hkl);

  for (i = 0, j = 2 * c - 1; i < c; ++i, --j)
  {
    ip[i].ki.dwFlags &= ~KEYEVENTF_KEYUP;
    ip[i].ki.wScan = rguScanCodes[i];
    ip[j].ki.dwFlags |= KEYEVENTF_KEYUP;
    ip[j].ki.wScan = rguScanCodes[i];
  }

  SendInput(2 * c, ip, sizeof(INPUT));

  if (fCapslock)
  {
    ip.ki.dwFlags &= ~KEYEVENTF_KEYUP;
    ip.ki.wScan = uCapslock;
    ip[1].ki.dwFlags |= KEYEVENTF_KEYUP;
    ip[1].ki.wScan = uCapslock;
    SendInput(2, ip, sizeof(INPUT));
  }

  return 0;
}

Bei diesem Code reicht es den ASCII Wert zu übergeben. Der Scancode wird mittels Keyboard Layout berechnet.

Grüße
rubberman
djevil-ad
djevil-ad 17.01.2015 um 11:14:13 Uhr
Goto Top
@114757

Danke so funktioniert es!

Die Scancodes sind aber falsch, was wohl an meinem Tastaturlayout liegt..,

@rubberman

Ui, dein Code ist mir unheimlich face-smile

108 Zeilen... das ist echt krass, für so ein vermeintlich kleines Projekt...

Aber, nein ich hatte nicht gedacht, dass es als nummerischer Wert eingeht, ich hatte gedacht, das es als char-Array eingeht,
darum wäre ich nicht auf die Idee gekommen es als String zu behandeln,(String to long)

Na ja, wie auch immer, vielen Dank!

Dann scliess ich das Thema jetzt.

Gruss djevil-ad
rubberman
rubberman 17.01.2015 um 14:37:09 Uhr
Goto Top
Hallo djevil-ad.

108 Zeilen... das ist echt krass, für so ein vermeintlich kleines Projekt...
Das ist eigentlich ein Hauch von Nichts bei einem C Projekt face-confused

Ein Minimum an vernünftiger Funktionalität und Fehlerabfrage sollte man schon implementieren. Dein Code geht schon unschön in die Knie, wenn du mal vergisst einen Parameter zu übergeben ...

Grüße
rubberman