Preliminary notes:
The title is kinda XY problem. It's good the question body clarifies your specific case. I mean you don't exactly want to "bitwise-OR 2 binary files", arbitrary files. You want to merge two HDD images, one of them was created by ddrescue.
dd is not the best tool for reading from faulty devices. conv=sync,noerr is often advised but it's not enough. Please read this. Unless you also used iflag=fullblock, the image generated by dd cannot be trusted. Having ddrescue I would not use dd at all. The right way to retry is to run ddrescue again with the same mapfile.
My answer assumes your image generated by dd can be trusted.
If you have the mapfile from the ddrescue run, then use --fill-mode.
When ddrescue is invoked with the --fill-mode option it operates in "fill mode", which is different from the default "rescue mode". That is, if you use the --fill-mode option, ddrescue does not rescue anything. It only fills with data read from infile the blocks of outfile whose status character from mapfile coincides with one of the type characters specified as argument to the --fill-mode option.
(source)
In your case it will be like:
ddrescue --OPTIONS --fill-mode='?*/-' image_from_dd image_from_ddrescue mapfile_from_ddrescue
where ?*/- mean:
? non-tried block
* failed block non-trimmed
/ failed block non-scraped
- failed block bad-sector(s)
And there's + you don't want in your command:
+ finished block
--OPTIONS denotes some options you originally used; options that, if changed, would make the tool misinterpret the mapfile. The set contains --sector-size for sure. Hint: the original command line may be stored in the mapfile as a comment.
If you used --input-position and/or --output-position (and/or skip= and/or seek= with dd) then some recalculations are required, I think. Without testing I cannot give you the right formula. You probably did not use these options anyway.
Thanks to --fill-mode all sectors that are not considered rescued by your original ddrescue will be filled with data taken from respective fragments of image_from_dd.
If the mapfile from the original ddrescue run is unavailable or if you really want to overwrite all sectors filled with zeros (even ones where ddrescue has actually read zeros without errors), then you should ask ddrescue to generate a mapfile:
When ddrescue is invoked with the --generate-mode option it operates in "generate mode", which is different from the default "rescue mode". That is, if you use the --generate-mode option, ddrescue does not rescue anything. It only tries to generate a mapfile for later use.
[…]
ddrescue can in some cases generate an approximate mapfile, from infile and the (partial) copy in outfile, that is almost as good as an exact mapfile. It makes this by simply assuming that sectors containing all zeros were not rescued.
[…]
Note that you must keep the original offset between --input-position and --output-position of the original rescue run.
(source)
The manual gives this example:
ddrescue --generate-mode infile outfile mapfile
but my tests indicate infile is only formally checked for existence and general sanity, then it doesn't matter; only outfile is used to generate mapfile. So you don't need the original HDD at all, the command may be:
ddrescue --generate-mode /dev/zero image_from_ddrescue new_mapfile
After it finishes you will have the new_mapfile. Use it with --fill-mode, like described above (--OPTIONS should match the relevant options used with --generate-mode).
Note you can work in the opposite direction: generate a (different) mapfile from image_from_dd and use --fill-mode to write parts of image_from_ddrescue into image_from_dd.