Two obvious paths come to mind:
1) I find out what the interface spec to the DLL is (which I may be able to extract from the DLL itself given enough talent and the right tools), then I right whatever coded I want that meets this spec. That is I provide classes and methods that the program loading the DLL expects, but behind them I do whatever I jolly well want. I then replace the original DLL i the distribution with my DLL and redistribute it. You acquire it somehow and run the program you trust and you're running my code when you do that. Not something you want to do because my code may well be scanning your PC for all sort of handy info to compromise your system and/or just spread a chest beating "I've done it" virus or any other kind of thing I want to do which you ran because you thought you were running some program you trusted.
2) I open the DLL in a hex editor and employing y extensive knowledge of the internal structure of DLLs identify a neat code entry point where in patch directly, knowing the encoding used in the DLL the binary code for a snippet of machine code I've written which does something snide and trivial yet undesirably to you, to or on your PC.
These boil down essentially to two scales of tampering.
1) replacing the DLL completely with my cleverly written yet disguised DLL.
2) Modifying the existing DLL with my code with my patches to it.
That should just about cover the tampering options. The rest is detail and a fair bit of low level knowledge on how this works. That is, no-one needing to read this article probably knows how ;-). People who tamper with DLLs already know stuff like how strong naming works and a heck of a lot more about how .NET and DLLs all hang together!