C++: C++ to machine code via TDM-GCC

Post a reply


In an effort to prevent automatic submissions, we require that you complete the following challenge.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: C++: C++ to machine code via TDM-GCC

Re: C++: C++ to machine code via TDM-GCC

Post by Helgef » 27 May 2018, 03:32

- I'm yet to have any problems with C/C++
I've got enough knowledge now to do some good codes.
I expected a different reaction :think:.
isn't it equally correct to say that we should edit the hex string for the machine code.
I wouldn't convert an address to a string only to convert it back to number. In this example, the 32 bit code needs an address, so it cannot be hard coded. The 64 bit needs a relative address so it can be hard coded. You also need to make sure the memory (of the constant 16 byte data in the example) is 16-byte aligned, varsetcapacity doesn't guarantee that. I use arrays for my binary code, often I can only insert stuff in the array when needed. If I used hex strings, I'd use numput on the allocated memory directly.
it looks like we need to know a bit about ASM
As I said in that thread, it is great for learning, but when you want to produce actual usable code, writing it in c / c++ is generally preferred.
nnnik wrote:This is just the beginning of issues.
Indeed we need pop corn emoticons on this forum.

Good luck, cheers.

Re: C++: C++ to machine code via TDM-GCC

Post by nnnik » 26 May 2018, 22:38

This is just the beginning of issues.
From my experience MCode works best when running completely dynamic code that does not have references towards other functions.
Your stredit function had a static outcome and you immediately get issues.
All those problems stem from catching the machine code before it gets send to the linker and turned into a dll or exe which gets correctly linked by the windows linker on runtime.
In the case of your broken function it would insert a pointer to the data that your code wants to write in the necessary places.
As soon as C pushes some work on the linker your function won't work and throws a 0xc0000005.
And C pushes work on the linker for more reasons than I can be bothered to learn.
https://msdn.microsoft.com/en-us/library/ms809762.aspx

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 18:07

- GREAT. I used the -O2 flag instead of the -O3 flag, and my function worked.
- I mentioned in the OP if anyone could suggest any good links for the TDM-GCC command-line parameters.

- So changing the command-line flag (TDM-GCC), and the fact that AStr modifies the string (AutoHotkey) have been the two problems I've experienced so far.
- I'm yet to have any problems with C/C++, but I'd highly recommend to the other posters (Helgef and nnnik) to learn more about C/C++. :angel:
- @Helgef: you recommended in the 'InBuf function currently 32-bit only' thread that focusing on C++ to machine code, might be a better use of time than focusing on ASM to machine code, generally speaking I agree. However, it looks like we need to know a bit about ASM, for use with C++, after all, with regard to O2/O3 at least.

- I heard NumPut/VarSetCapacity mentioned, isn't it equally correct to say that we should edit the hex string for the machine code.

- I found some threads that seemed relevant, but the explanations and examples were lacking, and thus not much use. I need info to help predict and resolve problems generally, and not the minimum information required to fix one machine code function.
MCode access violation on: long long >> arg - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/7125 ... -long-arg/
DllCall Error with MCode Function - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?t=683
DllCall: "UChar*", buffer vs. "UInt", & - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/5398 ... r-vs-uint/
basic MCode c++ array question - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/9065 ... -question/
MCode function + onlinegenerator (x86 and x64) - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/8928 ... 6-and-x64/
- Seeing as I didn't know for definite what the problem was, I had dozens of other candidate threads to go through.

- Many thanks to both of you for your help here, I've got enough knowledge now to do some good codes.

Re: C++: C++ to machine code via TDM-GCC

Post by Helgef » 26 May 2018, 17:29

What happens is that gcc optimises out the loop entirely for your stringedit function, instead it wants to read the first 16 bytes of the sequence 00,01,... in one instruction, because that is faster (yes, gcc figures out that the code can only have one outcome). How can we know? We can look at the assembly code, -S flag. What to do? Basically, you need to tell the machine code where to find these first 16 bytes, as hinted by nnnik, so numput/varsetcap it is. In general, this is not fun because every time you change your code, there is extra work, and 32 and 64 bit versions also differs. The simple solution is to avoid the optimisation, eg, try -O2 instead of -O3. You might eventually have found out that it would work with another flag, but you would not suddenly realise what is happening and you will not find it on google either, you will have endless debugging-from-hell issues (and certainly not only regarding optimisations) if you proceed without taking the advice to learn c/c++ first. You will have plenty such issues anyways ofc.

The exception probably comes from trying to dereference a null pointer, because you didn't provide a pointer (offset on 64 bit) to the data.

cheers :wave:

Re: C++: C++ to machine code via TDM-GCC

Post by nnnik » 26 May 2018, 12:21

You need to use VarSetCapacity and NumPut to modify the binary data of the MCode.

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 11:50

nnnik wrote:Well I guess I never mentioned that you need to use VarSetCapacity to initialize data in them then.
Did you fix this yet? Can you explain what you meant. Thanks.

Re: C++: C++ to machine code via TDM-GCC

Post by nnnik » 26 May 2018, 11:44

You should look for a beginners C++ tutorial before attempting this.

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 11:16

- Add VarSetCapacity to the script? Add a VarSetCapacity C++ equivalent to the C++ code?
- Any ideas re. what's causing the access violation? It seems that a lot of users have had that error when using machine code, but never got a response on the forum. Thanks.
- Or what, is 'char *str', a pointer, but not a 4-byte/8-byte number (depending on the OS), but 0.5 bytes!? So it needs to converted to be a ptr, or replaced with *something*?
Why C++ Member Function Pointers Are 16 Bytes Wide - Vlad Lazarenko
http://lazarenko.me/wide-pointers/

Re: C++: C++ to machine code via TDM-GCC

Post by Helgef » 26 May 2018, 07:35

It is called factorial in English ( n! )

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 07:35

Factorial - Wikipedia
https://en.wikipedia.org/wiki/Factorial
Fakultät (Mathematik) – Wikipedia
https://de.wikipedia.org/wiki/Fakult%C3 ... athematik)
Thanks, Google Translate didn't suggest it. And searches for mathematics and Fakultät just gave me faculties (institutions).

Re: C++: C++ to machine code via TDM-GCC

Post by nnnik » 26 May 2018, 07:31

Well I guess I never mentioned that you need to use VarSetCapacity to initialize data in them then.
the name might be wrong but on your calculator it normally looks like : n!

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 07:29

- @nnnik: Yes. Where did you come across this function: MyFunction(a-1,b*a), you call it the 'faculty' function, do you have a reference for it in German/English? Thanks.
- [EDIT:] Looking at it again the function pointer stuff looks like it could be relevant, but from reading the tutorial I'm not clear on what the nature of the problem and solution are.

Re: C++: C++ to machine code via TDM-GCC

Post by nnnik » 26 May 2018, 07:25

Did you really read both of my tutorials?

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 07:20

- If 15 works but 16 doesn't, that suggests that *something* can only handle a nibble (4 bits of information). Although some of my other functions suggested that there is no limit of 16.
- I looked through a tonne of links: AutoHotkey mcode "access violation", I didn't find any solution.

Re: C++: C++ to machine code via TDM-GCC

Post by Helgef » 26 May 2018, 07:05

So it worked for you didn't it?
I used my script :angel: .

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 06:50

Helgef wrote:It works as I expect, it returns 20 and initialises the char array as: 0, 1 ... 19
So it worked for you didn't it?

The error 0xc0000005 is access violation, suggesting a problem reading/writing data, however, the 1st of 4 stringedit examples successfully wrote to the first 20 bytes.

Re: C++: C++ to machine code via TDM-GCC

Post by Helgef » 26 May 2018, 06:23

Hello jeeswg :)
Hmm, it's a surprise that AStr is modifying the string, however!
I had thought that AHK would create a temporary variable based on vText, and pass that, leaving vText untouched.
It does create a temporary string based on vText and passes its address, but then, it updates vText to match this temporary string, this is sort of the purpose of using "xstr" vs "ptr", you avoid the need to do strput/get and varsetcapacity str,-1 when passing/retrieving strings. I suppose the documentation could explicitly state that both "astr" and "wstr" will update the variable as described for "str".
dllcall -> str wrote: A string such as "Blue" or MyVar. If the called function modifies the string and the argument is a naked variable, its contents will be updated. For example, the following call would convert the contents of MyVar to uppercase: DllCall("CharUpper", "Str", MyVar).
I think your main problem is that you had some false expectations on how chr(0x101) would be converted to an ansi character, passing "astr", chr(0x101) to dllcall is basically a lie and you got punished for lying.
I can't think why it isn't working for me
You will never figure it out unless you take my advice and take a course in c / c++, you need some basic understanding of optimising compilers. I'll give you a hint which you can ponder until your hair turns grey (or falls off, if it is already grey), if you change i<20 to i<15 your script will produce runnable code :morebeard:. Also, I recommend you use v2, or at least use try / check errorlevel for your your dllcalls. Doing this in v1 is painful :facepalm: .

Cheers.

Re: C++: C++ to machine code via TDM-GCC

Post by jeeswg » 26 May 2018, 04:59

YES. OK Helgef, here we are.
As you imply, if I comment out the AStr line, I get the 52 for the other lines that I was expecting.
AStr is *modifying* the string.
Hmm, it's a surprise that AStr is modifying the string, however!
I had thought that AHK would create a temporary variable based on vText, and pass that, leaving vText untouched.
(So perhaps you don't need to change your explanation. I'll give it a reread.)

Code: Select all

;MsgBox, % DllCall(stringlen, "AStr",vText, "Cdecl") ;26 ;if this line is called, the next 3 lines return 1
MsgBox, % DllCall(stringlen, "WStr",vText, "Cdecl") ;52
MsgBox, % DllCall(stringlen, "Str",vText, "Cdecl") ;52
MsgBox, % DllCall(stringlen, "Ptr",&vText, "Cdecl") ;52

MsgBox, % DllCall(stringlen2, "AStr",vText, "Cdecl") ;13
MsgBox, % DllCall(stringlen2, "WStr",vText, "Cdecl") ;26
MsgBox, % DllCall(stringlen2, "Str",vText, "Cdecl") ;26
MsgBox, % DllCall(stringlen2, "Ptr",&vText, "Cdecl") ;26
It's nice to know that my 4th stringedit function works for you, but I can't think why it isn't working for me. Could you post the machine code that you're getting? And/or check the code below. Thanks.

Code: Select all

q:: ;test byte write
vSize := 255
VarSetCapacity(vData, vSize, 0)
vFunc := MCode("2,x86:i0QkBGYPbwUAAAAAxkAQEMZAEREPEQDGQBISxkATE7gUAAAAw5CQkJCQkJCQkJCQAAECAwQFBgcICQoLDA0ODw==,x64:Zg9vBQAAAAC4FAAAAMZBEBDGQRERDxEBxkESEsZBExPDkJCQkJCQkJCQkJCQkJCQAAECAwQFBgcICQoLDA0ODw==")
MsgBox, % DllCall(vFunc, "Ptr",&vData, "Cdecl")

vOutput := ""
Loop, % vSize
	vOutput .= (A_Index=1?"":",") NumGet(&vData, A_Index-1, "UChar")
MsgBox, % vOutput
return

/*
int stringedit(char *str)
{
  int i=0;
  for (; i<20; i++)
    str[i]=i;
  return i;
}
*/

Re: C++: C++ to machine code via TDM-GCC

Post by Helgef » 26 May 2018, 03:30

// didn't work
It works as I expect, it returns 20 and initialises the char array as: 0, 1 ... 19
Apologies but I still don't see an explanation for the problem.
No need for apologies, I didn't see this comment I will try to see if I can better my explaination.

Edit:
jeeswg wrote:- If you could create a version of the stringlen function that works with Ptr, that might help to comprehend the situation better. Thanks.
Your stringlen code works, "astr", str modifies the string, if you omit that dllcall, you will get your expected result from "ptr", &str.

Cheers.

Re: C++: C++ to machine code via TDM-GCC

Post by nnnik » 25 May 2018, 23:28

You should probably repeat the chapter about strings and string encodings

Top