How to hide specific pages from users, but not the content? I'm trying to hide a specific set of pages from anonymous users and I would like to return a 404 for them. To be more precise, the set of pages I'm trying to hide are ECK entity pages (info blocks I guess), taxonomy term pages and a few node types. But I would like to still have them visible in the pages they are part of. 

To be more clear, let me give you an example : I would like to have itinerary/gallery/1 hidden from anonymous users, but I would still like for the gallery itself to be visible in the blog pages it's embedded in. 

I tried using the Rabbit Hole module and it works great for taxonomy terms and the node types, but not for the ECK stuff. I tried extending the module but it doesn't seem possible the way Rabbit Hole works unless I create an extension for each of them.

I also tried pulling a hook from hook_entity_view() but the problem with it is that it also triggers when the elements are loaded in the page, not just on their own pages. Does anyone have any idea how to do this?
You could use the Rules module to get this to work, by using the "Drupal is initializing" event. That will ensure that the rule gets triggered BEFORE the actual content is shown.

The links that you want to "intercept", should be formatted in some type of regular expression, which you then use as your Rules Condition. So that you have a rule that corresponds to "before showing the actual content of something that matches a specific path ...". After you get that part to work, your Rules Action should specify the actual redirect to be performed.

Sample rule

Refer to the "Option 1" part of my answer to the question about "How to restrict access to a node via node/12 and allow access via a path like content/sometitle?", which contains this rule in export format:

{ "rules_check_url" : {
    "LABEL" : "Disallow node/* access",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:url" ],
          "match" : "node\/\\d+$",
          "operation" : "regex"
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "Sorry, URLs like [site:current-page:url] are not allowed around here ...",
          "type" : "error"
        }
      },
      { "redirect" : { "url" : "no_access" } }
    ]
  }
}


Here are some suggested tunings of the above sample, to make it work for your case also:


machine name and label.
replace the node/* by your path(s) (in the regular expression).
possibly you may want to add an extra Rules Condition to only perform the Rules Actions for selected user roles (eg: only for user who are not administrators).
replace the path in the action part of the rule by your target path, and check if you do want some type of error message to be shown (if not remove that part of the action).