The basic concept used by the ghostcar mod for example is quite simple, you just place the D3D8.dll in the game directory, and because of the way LFS looks for the DLL's it will link that dll instead of the "real" one from the system32 dir.
Your DLL should export the same functions that the real one does, ie. Direct3DCreate8. When this function gets called you can do whatever you want in between and then call the real Direct3DCreate8 function and return whatever it returns to LFS. You can overwrite the COM interface function pointers to pointers to your own functions that again do what you want until doing the real thing.
The hardest part is knowing what to do and when, since what you get is a whole load of D3D functions passing through your DLL, with no idea what LFS is actually doing at that time. So you need to analyse all that data to find ways to recognise what LFS is doing. For example, you could detect that LFS is about to draw a car model by watching the currently active vertex shader ID's in SetVertexShader... GUI "additions" are somewhat easier, since you can just do your thing when LFS calls the Present function to display a completed frame. However you would still need to know when to do this so you wont draw over the options menus for example...