Author Topic: Using 32-bit code in 64-bit land  (Read 5468 times)

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5852
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Using 32-bit code in 64-bit land
« Reply #15 on: March 13, 2017, 11:00:39 PM »
For secure inter app communication you use a private message that is unique to your app and the other you are communicating with.

invoke PostMessage,HWND_BROADCAST,PM_YOURMESSAGE,0,0
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
Re: Using 32-bit code in 64-bit land
« Reply #16 on: March 14, 2017, 01:10:05 AM »
On topic: Does anybody have experience with ZwExtendSection? Apparently, it's the only way to implement a realloc on a memory-mapped file, but it's kind of undocumented...

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5852
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Using 32-bit code in 64-bit land
« Reply #17 on: March 14, 2017, 02:06:23 AM »
With a bit of messing around you could do this with the existing capacity without having to go to risky undocumented functions. Use messaging to tell both apps to shut down the existing MMF, send another message with the new size then send a message telling both to create a new MMF. Written properly it would work OK and probably be easily fast enough.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
Re: Using 32-bit code in 64-bit land
« Reply #18 on: March 14, 2017, 03:23:03 AM »
Complicated. Here is a shorter option:
Code: [Select]
mov rax, 8000000000
jinvoke CreateFileMapping, INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, rax, Chr$("~TmpObject")

Works fine and returns immediately.

adeyblue

  • Member
  • **
  • Posts: 89
    • Airesoft
Re: Using 32-bit code in 64-bit land
« Reply #19 on: March 14, 2017, 10:37:48 AM »
On topic: Does anybody have experience with ZwExtendSection? Apparently, it's the only way to implement a realloc on a memory-mapped file, but it's kind of undocumented...

It basically does this part of the CreateFileMapping documentation, but on demand.
Quote
If an application specifies a size for the file mapping object that is larger than the size of the actual named file on disk, the file on disk is increased to match the specified size of the file mapping object

It is only for mapped disk files that you've opened for writing. It'll fail if you instead pass NULL as the file handle to CreateFileMapping. Here's an example.

Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

extern "C"
DECLSPEC_IMPORT
long
WINAPI
NtExtendSection(HANDLE hMap, PLARGE_INTEGER pNewSize);

int main()
{
HANDLE hFile = CreateFileW(L"file.txt", GENERIC_ALL, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
if(hFile == INVALID_HANDLE_VALUE) {return printf("CreateFile fail - error %lu!\n", GetLastError());}
SetFilePointer(hFile, 1, NULL, FILE_BEGIN); // You can't map a 0 length file
SetEndOfFile(hFile);
DWORD size = GetFileSize(hFile, NULL);
printf("Original file size is %lu\n", size);
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 8192, NULL);
if(hMapping == NULL) {return printf("CreateFileMapping fail - error %lu!\n", GetLastError());}
size = GetFileSize(hFile, NULL);
printf("After CreateFileMapping, file size is %lu\n", size);
HANDLE hAllPermHandle = NULL;
// docs lie, CreateFileMapping doesn't create an all access handle
// it doesn't have SECTION_EXTEND_SIZE right which is required for NtExtendSection
// without this, NtExtendSection will fail with 0xc0000022 (STATUS_ACCESS_DENIED)
DuplicateHandle(GetCurrentProcess(), hMapping, GetCurrentProcess(), &hAllPermHandle, SECTION_ALL_ACCESS, FALSE, DUPLICATE_CLOSE_SOURCE);
if(hAllPermHandle == NULL) {return printf("DuplicateHandle fail - error %lu!\n", GetLastError());}
hMapping = hAllPermHandle;
PVOID pMapping = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
if(pMapping == NULL) {return printf("MapFileMapping fail - error %lu!\n", GetLastError());}
MEMORY_BASIC_INFORMATION mbi = {0};
VirtualQuery(pMapping, &mbi, sizeof(mbi));
printf("Mapped size is %Iu\n", mbi.RegionSize);

LARGE_INTEGER newSize = {16384};
long stat = NtExtendSection(hMapping, &newSize);
if(stat < 0) {return printf("NtExtendSection fail - err %#x\n", stat);}
size = GetFileSize(hFile, NULL);
printf("After NtExtendSection file size is %lu\n", size);
VirtualQuery(pMapping, &mbi, sizeof(mbi));
        // It doesn't update the mapped memory size though, you have to map any new bits yourself
printf("Mapped size after NtExtendSection is %Iu\n", mbi.RegionSize);
}

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
Re: Using 32-bit code in 64-bit land
« Reply #20 on: March 14, 2017, 11:16:43 AM »
It'll fail if you instead pass NULL as the file handle to CreateFileMapping.

You mean -1, INVALID_HANDLE_VALUE?

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
Re: Using 32-bit code in 64-bit land
« Reply #21 on: March 15, 2017, 04:23:49 AM »
Just for fun, attached a 64-bit application that calls a 32-bit server which translates Windows.inc into a string array using Recall. The 64-bit program prints the first n strings of the array to the console.

To test it, extract all files to a folder and start GetStringsFrom32BitLib.exe; afterwards, press O (like open) to see the first 39 strings and timings. For me (Core i5), it's around 100 ticks with printing 33 lines, and around 8 ticks when printing only one line (see source, line 93, .Until ct>32). Task manager looks OK, even if I keep the "O" pressed.

Every time you "open" the file, a 800MB MMF gets created (and closed):
   mov rax, 800000000
   jinvoke CreateFileMapping, INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, rax, Chr$("~TmpObject")

adeyblue

  • Member
  • **
  • Posts: 89
    • Airesoft
Re: Using 32-bit code in 64-bit land
« Reply #22 on: March 15, 2017, 04:57:48 AM »
It'll fail if you instead pass NULL as the file handle to CreateFileMapping.

You mean -1, INVALID_HANDLE_VALUE?

NULL is accepted as -1 (or rather -1 is converted to NULL), so they're equivalent for CreateFileMapping.

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
Re: Using 32-bit code in 64-bit land
« Reply #23 on: March 15, 2017, 06:05:20 AM »
NULL is accepted as -1 (or rather -1 is converted to NULL)

You have hacked the CreateFileMapping source :eusa_naughty:

Under the hood, 000007FEFD3F19D2:
Code: [Select]
000007FEFD3F19C4 | 4C 8D 4C 24 40                       | lea r9, qword ptr ss:[rsp+40]                 |
000007FEFD3F19C9 | 89 44 24 40                          | mov dword ptr ss:[rsp+40], eax                |
000007FEFD3F19CD | 44 89 6C 24 44                       | mov dword ptr ss:[rsp+44], r13d               |
000007FEFD3F19D2 | 48 83 FD FF                          | cmp rbp, FFFFFFFFFFFFFFFF                     |
000007FEFD3F19D6 | 0F 84 C4 00 00 00                    | je 7FEFD3F1AA0                                |
@@:
000007FEFD3F19DC | 83 FE FF                             | cmp esi, FFFFFFFF                             |
000007FEFD3F19DF | 0F 85 23 D5 00 00                    | jne 7FEFD3FEF08                               |
...
000007FEFD3F1AA0 | 4D 85 C9                             | test r9, r9                                   |
000007FEFD3F1AA3 | 0F 84 E5 D3 00 00                    | je 7FEFD3FEE8E                                |
000007FEFD3F1AA9 | 33 ED                                | xor ebp, ebp                                  |
000007FEFD3F1AAB | E9 2C FF FF FF                       | jmp @B   ;7FEFD3F19DC                               |

So -1 and 0 work - and no other value :t

Slightly odd the test r9, r9 at AA0; there is no such test if you pass handle zero, and with the lea r9, [rsp+40], it can never be zero ::)

Btw this is the limit on my 4GB RAM machine - slightly under one GB:
Code: [Select]
mov rax, 1020000000
jinvoke CreateFileMapping, -1, NULL, PAGE_READWRITE, 0, rax, Chr$("~TmpObject")

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
Long live DDE for Excel!
« Reply #24 on: May 04, 2018, 06:40:37 PM »
How many times did they try to discourage people from using DDE ("Atoms and Shared Memory Objects")? It still works with Micros**t Office...

EDIT: Apparently, DDE does no longer work with Excel 2016:
Quote
Anonymous commented  ยท  January 12, 2017

I agree with anonymous October 6, 2016. Mail merge is now a nightmare!

Users trying to blackmail Micros**t ("If it is not included we never update our office Package to a newer Version in the whole company"): 47 comments (and M$ regularly deletes older comments). Yeah, long live DDE :t

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
mov rax, [ebx]
« Reply #25 on: June 05, 2018, 11:09:24 PM »
Is mov rax, [ebx] possible? Test yourself...
Code: [Select]
include \Masm32\MasmBasic\Res\JBasic.inc
Init ; OPT_64 1 ; put 0 for 32 bit, 1 for 64 bit assembly
  push rax ; keep align 16
  push 11111111h
  mov rbx, rsp
  mov eax, [ebx]
  Print Str$("eax=%x\n", eax) ; result: 11111111h
  add rsp, SIZE_P*2
  push rax ; keep align 16
  push 22222222h
  mov rbx, rsp
  mov rax, [ebx] ; <<<<<<<<<<<<<<
  Inkey Str$("rax=%x\n", rax) ; result: 22222222h
  add rsp, SIZE_P*2
EndOfCode

felipe

  • Member
  • ****
  • Posts: 944
  • Eagles are just great!
Re: Using 32-bit code in 64-bit land
« Reply #26 on: June 06, 2018, 04:37:16 AM »
Don't know. Seems like that Init and others expand to a lot of code...You know, i'm just guessing... :idea:

Felipe.

jj2007

  • Member
  • *****
  • Posts: 8776
  • Assembler is fun ;-)
    • MasmBasic
Re: Using 32-bit code in 64-bit land
« Reply #27 on: June 06, 2018, 05:46:04 AM »
Don't know. ... just guessing
Why do you post if you don't know anything, and are just guessing? To increase your post count? You won't get a banana if you reach your 1,000 posts. Concentrate on your code, and eliminate your bugs, Felipe.

felipe

  • Member
  • ****
  • Posts: 944
  • Eagles are just great!
Re: Using 32-bit code in 64-bit land
« Reply #28 on: June 06, 2018, 05:51:00 AM »
Why get a banana if you reach 1,000. Concentrate on your bugs, Felipe.

You are right.  :icon14:
Felipe.

sinsi

  • Member
  • *****
  • Posts: 1072
Re: Using 32-bit code in 64-bit land
« Reply #29 on: June 06, 2018, 09:08:01 AM »
> Is mov rax, [ebx] possible?
Even mov rax,[bx] is possible, as long as bx points to valid memory (hint: it doesn't in most modern OSes).
I can walk on water but stagger on beer.