Mcode DllCall - How to return an array? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
terrypaton2
Posts: 30
Joined: 03 Aug 2018, 20:35

Mcode DllCall - How to return an array?

03 Aug 2018, 21:10

I am a newbie, I am trying to return a int array from machine code by Dllcall. I can call the code, but when I try get a element of array , I recieved a blank value.

ahk code:

Code: Select all

CheckDup:=Mcode("2,x64:SI0FAAAAAMOQkJCQkJCQkAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")
E := DllCall( CheckDup,"Cdecl Ptr")
msgbox % E[1]
MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
	return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
	return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
	DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
	return p
  DllCall("GlobalFree", "ptr", p)
}
this is my c code

Code: Select all

int * funcarr()
{	
    static int arr[10]={1,2,3,4,5,6,7,8,9,0};
    
    return arr;
}
Last edited by terrypaton2 on 03 Aug 2018, 22:33, edited 1 time in total.
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Mcode DllCall - How to return an array?

03 Aug 2018, 21:38

an AHK array and a C array are not going to be compatible. not sure why you think they would be. maybe depending on how the C array is stored, you could use NumGet in AHK to get the memory stored at a certain byte offset

terrypaton2
Posts: 30
Joined: 03 Aug 2018, 20:35

Re: Mcode DllCall - How to return an array?

03 Aug 2018, 22:40

guest3456 wrote:an AHK array and a C array are not going to be compatible. not sure why you think they would be. maybe depending on how the C array is stored, you could use NumGet in AHK to get the memory stored at a certain byte offset
Numget return the binary number like this "15423648984" but I need to get elements of array, how can I get elements of array?
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 00:40

Could you post the code that contains the NumGet?
You should probably post an assembly listing of your MCode too.
Recommends AHK Studio
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 00:42

i don't think you understood what i wrote

i dont know how int[] arrays are stored in C. but as i remember char[] arrays are just sequences of bytes. so why not create a char[] array with your numbers, then just return the char variable, which should indicate the address in memory. then numget each offset and chr() the result

User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 01:33

Yeah it might be that MCode isnt able to return the correct address as the address is only determed upon loading the code into memory.
I think in 64 bit there was the possibility to use pointers relative to the current address so it might work.
However its still likely that the functions code and the data from the array ended up in different segments and depending on the compiler used the final MCode wont even contain the segment of the array.
Thats why we need more information:
Which MCode compler did you use. Which settings did you use?
Recommends AHK Studio
terrypaton2
Posts: 30
Joined: 03 Aug 2018, 20:35

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 03:12

@nnnik I use MCode4GCC (https://github.com/joedf/MCode4GCC), I use GCC compiler TDM-GCC-64 and set optimization -O3
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 03:31

And the assembly listing (thats more important) and could you output your code as hex since I cannot read base64.
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 03:44

The static data is not linked to the running code, you have to link it yourself. I recommend you pass an array instead, it is easier, and more modular. @ nnnik, as you guessed, a relative address is required.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 03:53

He could use my compiler instead but it currently only works for x86.
And uses Visual Studio.
I'd have to add documentation and a few settings though first.
Recommends AHK Studio
terrypaton2
Posts: 30
Joined: 03 Aug 2018, 20:35

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 03:54

nnnik wrote:And the assembly listing (thats more important) and could you output your code as hex since I cannot read base64.
Is this assembly listing?

Code: Select all

   1              		.file	"checkdupplicate - Copy.c"
   2              		.section	.text.unlikely,"x"
   3              	.LCOLDB0:
   4              		.text
   5              	.LHOTB0:
   6              		.p2align 4,,15
   7              		.globl	funcarr
   8              		.def	funcarr;	.scl	2;	.type	32;	.endef
   9              		.seh_proc	funcarr
  10              	funcarr:
  11              		.seh_endprologue
  12 0000 488D0500 		leaq	arr.1834(%rip), %rax
  12      000000
  13 0007 C3       		ret
  14              		.seh_endproc
  15              		.section	.text.unlikely,"x"
  16              	.LCOLDE0:
  17              		.text
  18              	.LHOTE0:
  19 0008 90909090 		.data
  19      90909090 
  20              		.align 32
  21              	arr.1834:
  22 0000 01000000 		.long	1
  23 0004 02000000 		.long	2
  24 0008 03000000 		.long	3
  25 000c 04000000 		.long	4
  26 0010 05000000 		.long	5
  27 0014 06000000 		.long	6
  28 0018 07000000 		.long	7
  29 001c 08000000 		.long	8
  30 0020 09000000 		.long	9
  31 0024 00000000 		.long	0
  32 0028 00000000 		.ident	"GCC: (tdm64-1) 5.1.0"
  32      00000000 
  32      00000000 
  32      00000000 
  32      00000000 
hex code

Code: Select all

488D0500000000C39090909090909090010000000200000003000000040000000500000006000000070000000800000009000000000000000000000000000000000000000000000000000000
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 04:02

Code: Select all

488D0500 		leaq	arr.1834(%rip), %rax
  12      000000
that is relative address , it is set to 00000000, you can change that to point to the array start: 22 0000 01000000 .long 1
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Mcode DllCall - How to return an array?

04 Aug 2018, 04:05

Yeah thats the assembly listing.
You are in luck since the compiler creates a relative addres so the linking shouldn't be too painful.
It also seems like joedfs compiler included the data of the array (I guessed that much since the MCode looked afully long for mov rax, static value + ret)
But you are using MCode for something I wouldnt recommend doing with it.
Unless I finish my compiler stuff like this is only going to be more work than it is worth.
Recommends AHK Studio
terrypaton2
Posts: 30
Joined: 03 Aug 2018, 20:35

Re: Mcode DllCall - How to return an array?  Topic is solved

04 Aug 2018, 05:15

Thank to @nnnik, @Helgef, @guest3456 for help. I passing my array to dllcall and handle it in c code, then I use NumGet to get element of array, now Its working.

ahk code

Code: Select all

global myarr

F1::

VarSetCapacity(myarr, 40,0)

str:=str "2,x64:SInIxwEAAAAAx0EEAQAAAMdBCAIAAADHQQwDAAAAx0EQBAAAAMdBFAUAAADHQRgGAAAAx0EcBwAAAMdBIAgAAADHQSQJAAAAw5CQkJCQkJA="

CheckDup:=Mcode(str)

E := DllCall( CheckDup,"int",&myarr,"int","Cdecl int")

loop 10
{
msgbox %  NumGet(myarr,(A_index-1)*4,"int")
}

return
MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
	return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
	return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
	DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
	return p
  DllCall("GlobalFree", "ptr", p)
}
c code:

Code: Select all

int * funcarr(int arr[])
{	
    for(int i=0;i<10;i++){
		arr[i]=i;
	}
    return arr;
}


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: aitaixy, Anput, Nerafius, RandomBoy and 189 guests