Author Topic: Working DLL  (Read 3608 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Working DLL
« on: April 04, 2004, 05:12:15 PM »
I got a very minimal DLL to compile and run. The game didn't crash and I didn't have to patch anythign with a hex editor this time.

All it does so far is set the player race, color and starting ore for two players. Basically, just enough so I know it works. The code still contains a bit of a hack though. Anyways, op2hacker I could probably use some of your help at this moment. You probably know a lot more than I do about some of the stuff that needs to be worked on.

Offline BlackBox

  • Administrator
  • Hero Member
  • *****
  • Posts: 3093
Working DLL
« Reply #1 on: April 05, 2004, 07:17:05 AM »
Edit: I read the other thread and saw the hack.

Anyway, you'll have to talk to me directly on IRC, AIM, or something else....

I noticed that I missed you yesterday on IRC....

Well, I'm sure we'll get in touch sometime.
« Last Edit: April 05, 2004, 07:18:57 AM by op2hacker »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Working DLL
« Reply #2 on: April 07, 2004, 01:12:34 AM »
Thanks for the support, and double thanks for that starter project.

Anyways, I've gone back to your original project to figure out exactly what changes I needed to make. Oh, and just to clairify, I got a working DLL without haveing to use the export forwarding trick. Anyways, here is a list of the changes:

1) In Template.h, move the DescBlock line to the end of the data declarations. I somehow got the feeling it may be more than 4 bytes and moving this was the last step that got things working for me. Also, this export was always after the other data exports in the data section of the original DLLs.

2) Change the Entry Point (Project->Settings->Link->Output) to DllMain. This cuts out any CRT code. I actually did this first to get rid of the annoying message box that my "Introductory" compiler puts into all compiled code.

3) Well your at the last screen, it doesn't hurt to set the base to 0x11000000 to match the other DLLs. It probably makes for a faster load but doesn't seem to be required.

Well, that was it to get a do nothing DLL. I was surprised when it suddenly started working for me.


Exporting data seems to have some issues that I've been reading about. I noticed this when tyring to use the exported Player variable. Maybe I'm doing it wrong but I had to use some ugly/bad casting hack to get a working pointer to _Player, but once I had it, the function calls worked fine. No matter how I changed things around, I couldn't get the compiler to generate the right code without the cast. It always had an extra level of indirection or it just wouldn't use the exported variable. If you check the decomiled code the compiler generates and compare it to one of the original DLLs, you'll see what I mean.

I'm also a little puzzled about how certain calls are supposed to be made. In particular, the code I've seen in the DLLs for calling CreateUnit doesn't even come close to matching anything I can get my compiler to create. I'm going to look into this next when I get the time.

Meanwhile, it might help if I understood the import library a little more. In particular, I'm wondering what method you used to create it. I read a bit about using Lib.exe to create one and figured I'd try exploring that myself but it didn't quite work. I think I lost some "?"s at the beginning of names. Possibly because of how I created the .def file from DUMPBIN (or rather how I edited it). It this what you did?

Anyways, I'm probably not going to be easy to reach for the next few days/weeks. Lots of projects comming due and finals approaching. I hope those tips help. Have fun with it.
 

Offline BlackBox

  • Administrator
  • Hero Member
  • *****
  • Posts: 3093
Working DLL
« Reply #3 on: April 07, 2004, 07:30:51 AM »
Yes, I was talking to Cynex the other day on IRC.

You'll be pretty surprised at what happened.

He discovered that yes, DescBlock is 64 bits long (a QUAD). But the real important discovery is he was able to create a working DLL that did execute stuff like CreateUnit, etc.

What he did was to create a DLL with MASM32, and instead of linking with the MS linker, he downloaded a linker called GoLink and linked with that. What that does is take already compiled input files (ie. Outpost2.exe, other DLL's, other EXE's) and scan the OBJ files from the compiler (it supports COFF-format files) checking for references to functions from the DLLs/EXEs and links them in. In other words, it doesn't require LIB files.

He said his DLL compiled to 6 KB (since there are no runtimes, etc)

He said his method worked 100%, however I have not tested it out yet.

The downside is that all the code was written in ASM.... He figures that the GoLink linker could be used with C++ output OBJ's...

This all explains why OP2 exports wsprintf() from it's EXE..... so the DLL's don't have to be bloated with the runtime....

Anyway, this is the document I looked at for making the LIB:
http://support.microsoft.com/default.aspx?...kb;en-us;131313

As far as the _Player casting hack, could you post that here?

-- op2hacker

Offline Cynex

  • Newbie
  • *
  • Posts: 31
Working DLL
« Reply #4 on: April 07, 2004, 11:58:46 AM »
Yes I got it working

As Hooman said i also suggest to set the entry-point at 11000000h since it seems to be more compatible with debuggers.
Otherwise the system may relocate it when loading the dll.

I use GoLink because it creates direct references to the exported functions if you "call dword ptr [function]" (when "call function" it'll redirect to jumptable however.

In this case use a macro like the following to load a register with the address of the importet variable:

LoadPlayer MACRO reg32
   lea reg32, dword ptr [Player]
   mov reg32, dword ptr [reg32 + 2]
ENDM

Edit:

Just discovered that MSVC++ (unlike most assemblers I used) is able to create direct references quite easily using the __declspec(dllimport) directive.
http://msdn.microsoft.com/library/en-us/vc....asp?frame=true

The problem you have seems to be different.
« Last Edit: April 07, 2004, 09:55:03 PM by Cynex »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Working DLL
« Reply #5 on: April 09, 2004, 03:17:07 AM »
Cool. I'll have to give this another try in assembly. It seems almost easier at times, however I tried using MASM32 to create a DLL and it always failed to load. I never really did figure out why. Probably something simple. Anyways, are there any other useful tidbits of info for writing a DLL in assembly? Oh, and is there any additional info on DescBlock that you can post?

I posted the casting code in another thread.

Also, when playing around with CreateUnit, I found that the compiled DLL made a reference to a nonexistent function. It seems to link to "...AAULOCATION..." instead of "...ULOCATION...". I tried fixing the .lib file with a hex editor but that just messed it up. Any way you know of fixing that hacker? I know fixing the import table of the DLL makes it work. Hmm... maybe I'll just play around with it some more.

Edit: It appears the CreateUnit function is missing a parameter. I count 5 parameters on the stack and 2 in registers. Everywhere I look only detects 6 of them.
« Last Edit: April 09, 2004, 02:54:19 PM by Hooman »